/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ package org.apache.ode.daohib.bpel; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ode.bpel.common.BpelEventFilter; import org.apache.ode.bpel.common.InstanceFilter; import org.apache.ode.bpel.dao.*; import org.apache.ode.bpel.evt.BpelEvent; import org.apache.ode.bpel.evt.ScopeEvent; import org.apache.ode.daohib.SessionManager; import org.apache.ode.daohib.bpel.hobj.*; import org.apache.ode.daohib.bpel.ql.HibernateInstancesQueryCompiler; import org.apache.ode.ql.eval.skel.CommandEvaluator; import org.apache.ode.ql.tree.Builder; import org.apache.ode.ql.tree.BuilderFactory; import org.apache.ode.ql.tree.nodes.Query; import org.apache.ode.utils.SerializableUtils; import org.apache.ode.utils.stl.CollectionsX; import org.apache.ode.utils.stl.UnaryFunctionEx; import org.hibernate.Criteria; import org.hibernate.FetchMode; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.criterion.Expression; import org.hibernate.criterion.Projections; import javax.xml.namespace.QName; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.sql.Timestamp; import java.util.*; /** * Hibernate-based {@link BpelDAOConnection} implementation. */ class BpelDAOConnectionImpl implements BpelDAOConnection { private static final Log __log = LogFactory.getLog(BpelDAOConnectionImpl.class); private Session _session; private SessionManager _sm; BpelDAOConnectionImpl(SessionManager sm) { _sm = sm; _session = _sm.getSession(); } public MessageExchangeDAO createMessageExchange(char dir) { HMessageExchange mex = new HMessageExchange(); mex.setDirection(dir); _session.save(mex); return new MessageExchangeDaoImpl(_sm, mex); } public MessageExchangeDAO getMessageExchange(String mexid) { HMessageExchange mex = (HMessageExchange) _session.get(HMessageExchange.class, new Long(mexid)); return mex == null ? null : new MessageExchangeDaoImpl(_sm, mex); } public ProcessDAO createProcess(QName pid, QName type, String guid, long version) { HProcess process = new HProcess(); process.setProcessId(pid.toString()); process.setTypeName(type.getLocalPart()); process.setTypeNamespace(type.getNamespaceURI()); process.setDeployDate(new Date()); process.setGuid(guid); process.setVersion(version); _session.save(process); return new ProcessDaoImpl(_sm, process); } public ProcessDAO getProcess(QName processId) { try { Criteria criteria = _session.createCriteria(HProcess.class); criteria.add(Expression.eq("processId", processId.toString())); // For the moment we are expecting only one result. HProcess hprocess = (HProcess) criteria.uniqueResult(); return hprocess == null ? null : new ProcessDaoImpl(_sm, hprocess); } catch (HibernateException e) { __log.error("DbError", e); throw e; } } public void close() { } /** * @see org.apache.ode.bpel.dao.ProcessDAO#getInstance(java.lang.Long) */ public ProcessInstanceDAO getInstance(Long instanceId) { return _getInstance(_sm, _session, instanceId); } public ScopeDAO getScope(Long siidl) { return _getScope(_sm, _session, siidl); } public Collection<ProcessInstanceDAO> instanceQuery(InstanceFilter criteria) { if (criteria.getLimit() == 0) { return Collections.emptyList(); } List<ProcessInstanceDAO> daos = new ArrayList<ProcessInstanceDAO>(); Iterator<HProcessInstance> iter = _instanceQuery(_session, false, criteria); while (iter.hasNext()) { daos.add(new ProcessInstanceDaoImpl(_sm, iter.next())); } return daos; } @SuppressWarnings("unchecked") static Iterator<HProcessInstance> _instanceQuery(Session session, boolean countOnly, InstanceFilter filter) { Criteria crit = session.createCriteria(HProcessInstance.class); CriteriaBuilder cb = new CriteriaBuilder(); cb.buildCriteria(crit, filter); return crit.list().iterator(); } static ProcessInstanceDAO _getInstance(SessionManager sm, Session session, Long iid) { HProcessInstance instance = (HProcessInstance) session.get(HProcessInstance.class, iid); return instance != null ? new ProcessInstanceDaoImpl(sm, instance) : null; } static ScopeDAO _getScope(SessionManager sm, Session session, Long siid) { HScope scope = (HScope) session.get(HScope.class, siid); return scope != null ? new ScopeDaoImpl(sm, scope) : null; } public void insertBpelEvent(BpelEvent event, ProcessDAO process, ProcessInstanceDAO instance) { _insertBpelEvent(_sm.getSession(), event, process, instance); } /** * Helper method for inserting bpel events into the database. * * @param sess * @param event * @param process * @param instance */ static void _insertBpelEvent(Session sess, BpelEvent event, ProcessDAO process, ProcessInstanceDAO instance) { HBpelEvent hevent = new HBpelEvent(); hevent.setTstamp(new Timestamp(System.currentTimeMillis())); hevent.setType(BpelEvent.eventName(event)); hevent.setDetail(event.toString()); if (process != null) hevent.setProcess((HProcess) ((ProcessDaoImpl) process).getHibernateObj()); if (instance != null) hevent.setInstance((HProcessInstance) ((ProcessInstanceDaoImpl) instance).getHibernateObj()); if (event instanceof ScopeEvent) hevent.setScopeId(((ScopeEvent) event).getScopeId()); try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(event); oos.flush(); HLargeData ld = new HLargeData(bos.toByteArray()); hevent.setData(ld); sess.save(ld); } catch (Throwable ex) { // this is really unexpected. __log.fatal("InternalError: BpelEvent serialization failed.", ex); } sess.save(hevent); } @SuppressWarnings( { "unchecked", "deprecation" }) public List<Date> bpelEventTimelineQuery(InstanceFilter ifilter, BpelEventFilter efilter) { CriteriaBuilder cb = new CriteriaBuilder(); Criteria crit = _session.createCriteria(HBpelEvent.class); if (ifilter != null) cb.buildCriteria(crit, efilter); if (ifilter != null) cb.buildCriteria(crit.createCriteria("instance"), ifilter); crit.setFetchMode("tstamp", FetchMode.EAGER); crit.setProjection(Projections.property("tstamp")); return crit.list(); } @SuppressWarnings("unchecked") public List<BpelEvent> bpelEventQuery(InstanceFilter ifilter, BpelEventFilter efilter) { CriteriaBuilder cb = new CriteriaBuilder(); Criteria crit = _session.createCriteria(HBpelEvent.class); if (efilter != null) cb.buildCriteria(crit, efilter); if (ifilter != null) cb.buildCriteria(crit.createCriteria("instance"), ifilter); List<HBpelEvent> hevents = crit.list(); List<BpelEvent> ret = new ArrayList<BpelEvent>(hevents.size()); try { CollectionsX.transformEx(ret, hevents, new UnaryFunctionEx<HBpelEvent, BpelEvent>() { public BpelEvent apply(HBpelEvent x) throws Exception { return (BpelEvent) SerializableUtils.toObject(x.getData().getBinary(), BpelEvent.class .getClassLoader()); } }); } catch (Exception ex) { __log.fatal("Internal error: unable to transform HBpelEvent", ex); throw new RuntimeException(ex); } return ret; } /** * @see org.apache.ode.bpel.dao.BpelDAOConnection#instanceQuery(String) */ @SuppressWarnings("unchecked") public Collection<ProcessInstanceDAO> instanceQuery(String expression) { Builder<String> builder = BuilderFactory.getInstance().createBuilder(); final org.apache.ode.ql.tree.nodes.Node rootNode = builder.build(expression); HibernateInstancesQueryCompiler compiler = new HibernateInstancesQueryCompiler(); CommandEvaluator<List, Session> eval = compiler.compile((Query) rootNode); List<HProcessInstance> instancesList = (List<HProcessInstance>) eval.evaluate(_session); Collection<ProcessInstanceDAO> result = new ArrayList<ProcessInstanceDAO>(instancesList.size()); for (HProcessInstance instance : instancesList) { result.add(getInstance(instance.getId())); } return result; } }