/* * 2012-3 Red Hat Inc. and/or its affiliates and other contributors. * * 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. */ package org.overlord.rtgov.activity.store.jpa; import java.net.URL; import java.text.MessageFormat; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.inject.Singleton; import org.hibernate.Session; import org.overlord.rtgov.activity.model.ActivityType; import org.overlord.rtgov.activity.model.ActivityUnit; import org.overlord.rtgov.activity.model.Context; import org.overlord.rtgov.activity.server.ActivityStore; import org.overlord.rtgov.activity.server.QuerySpec; import org.overlord.rtgov.activity.util.ActivityUtil; import org.overlord.rtgov.common.jpa.JpaStore; import org.overlord.rtgov.common.jpa.JpaStore.JpaWork; /** * This class provides the JPA implementation of the Activity Store. * */ @SuppressWarnings("deprecation") @Singleton public class JPAActivityStore implements ActivityStore { private static final Logger LOG = Logger.getLogger(JPAActivityStore.class.getName()); private static final String JNDI_PROPERTY = "JPAActivityStore.jndi.datasource"; private final JpaStore _jpaStore; /** * Constructor. */ public JPAActivityStore() { final URL configXml = this.getClass().getClassLoader().getResource("activitystore.hibernate.cfg.xml"); _jpaStore = new JpaStore(configXml, JNDI_PROPERTY); } /** * Constructor. * * @param jpaStore Explicit JpaStore to use */ public JPAActivityStore(JpaStore jpaStore) { _jpaStore = jpaStore; } /** * {@inheritDoc} */ public void store(final List<ActivityUnit> activities) throws Exception { if (LOG.isLoggable(Level.FINEST)) { LOG.finest("Store=" + new String(ActivityUtil.serializeActivityUnitList(activities))); } _jpaStore.withJpa(new JpaWork<Void>() { public Void perform(Session s) { for (int i = 0; i < activities.size(); i++) { s.persist(activities.get(i)); } return null; } }); } /** * {@inheritDoc} */ public ActivityUnit getActivityUnit(final String id) throws Exception { if (LOG.isLoggable(Level.FINEST)) { LOG.finest("Get Activity Unit=" + id); } ActivityUnit ret = _jpaStore.withJpa(new JpaWork<ActivityUnit>() { public ActivityUnit perform(Session s) { return (ActivityUnit) s.createQuery( "SELECT au FROM ActivityUnit au WHERE au.id = '" + id + "'").uniqueResult(); } }); if (LOG.isLoggable(Level.FINEST)) { LOG.finest("ActivityUnit id=" + id + " Result=" + new String(ActivityUtil.serializeActivityUnit(ret))); } return (ret); } /** * {@inheritDoc} */ @SuppressWarnings("unchecked") public java.util.List<ActivityType> getActivityTypes(final Context context, final long from, final long to) throws Exception { List<ActivityType> ret = null; if (from == 0 && to == 0) { if (context == null) { throw new Exception(java.util.PropertyResourceBundle.getBundle( "activity-store-jpa.Messages").getString("ACTIVITY-STORE-JPA-3")); } ret = _jpaStore.withJpa(new JpaWork<List<ActivityType>>() { public List<ActivityType> perform(Session s) { return (List<ActivityType>) s.createQuery( "SELECT at from ActivityType at " + "JOIN at.context ctx " + "WHERE ctx.value = '" + context.getValue() + "' " + "AND ctx.type = '" + context.getType().name() + "'").list(); } }); } else { final long actualTo = (to == 0 ? System.currentTimeMillis() : to); if (context == null) { ret = _jpaStore.withJpa(new JpaWork<List<ActivityType>>() { public List<ActivityType> perform(Session s) { return (List<ActivityType>) s.createQuery( "SELECT at from ActivityType at " + "WHERE at.timestamp >= " + from + " " + "AND at.timestamp <= " + actualTo).list(); } }); } else { ret = _jpaStore.withJpa(new JpaWork<List<ActivityType>>() { public List<ActivityType> perform(Session s) { return (List<ActivityType>) s.createQuery( "SELECT at from ActivityType at " + "JOIN at.context ctx " + "WHERE ctx.value = '" + context.getValue() + "' " + "AND ctx.type = '" + context.getType().name() + "' " + "AND at.timestamp >= " + from + " " + "AND at.timestamp <= " + actualTo).list(); } }); } } if (LOG.isLoggable(Level.FINEST)) { LOG.finest("ActivityTypes context '" + context + "' from=" + from + " to=" + to + " Result=" + new String(ActivityUtil.serializeActivityTypeList(ret))); } return (ret); } /** * {@inheritDoc} */ public List<ActivityType> getActivityTypes(Context context) throws Exception { return (getActivityTypes(context, 0, 0)); } /** * {@inheritDoc} */ public List<ActivityType> query(QuerySpec query) throws Exception { if (LOG.isLoggable(Level.FINEST)) { LOG.finest("Query=" + query); } if (query.getFormat() == null || !query.getFormat().equalsIgnoreCase("jpql")) { throw new IllegalArgumentException(MessageFormat.format(java.util.PropertyResourceBundle .getBundle("activity-store-jpa.Messages").getString("ACTIVITY-STORE-JPA-1"), (query .getFormat() == null ? "" : query.getFormat()))); } if (query.getExpression() == null || !query.getExpression().toLowerCase().startsWith("select ")) { throw new IllegalArgumentException(java.util.PropertyResourceBundle.getBundle( "activity-store-jpa.Messages").getString("ACTIVITY-STORE-JPA-2")); } return (query(query.getExpression())); } /** * This method performs the query associated with the supplied query * expression, returning the results as a list of activity types. * * @param query * The query expression * @return The list of activity types * @throws Exception * Failed to perform query */ @SuppressWarnings("unchecked") public List<ActivityType> query(final String query) throws Exception { List<ActivityType> ret = _jpaStore.withJpa(new JpaWork<List<ActivityType>>() { public List<ActivityType> perform(Session s) { return (List<ActivityType>) s.createQuery(query).list(); } }); if (LOG.isLoggable(Level.FINEST)) { LOG.finest("Query=" + query + " Result=" + new String(ActivityUtil.serializeActivityTypeList(ret))); } return (ret); } /** * This method removes the supplied activity unit. * * @param au * The activity unit * @throws Exception * Failed to remove activity unit */ public void remove(final ActivityUnit au) throws Exception { _jpaStore.withJpa(new JpaWork<Void>() { public Void perform(Session s) { // Cascading delete is not working from activity unit to // activity types, // so resorting to native SQL for now to delete an activity unit // and its // associated components s.createSQLQuery("DELETE FROM RTGOV_ACTIVITY_CONTEXT WHERE unitId = '" + au.getId() + "'") .executeUpdate(); s.createSQLQuery("DELETE FROM RTGOV_ACTIVITY_PROPERTIES WHERE unitId = '" + au.getId() + "'") .executeUpdate(); s.createSQLQuery("DELETE FROM RTGOV_ACTIVITIES WHERE unitId = '" + au.getId() + "'") .executeUpdate(); s.createSQLQuery("DELETE FROM RTGOV_ACTIVITY_UNITS WHERE id = '" + au.getId() + "'") .executeUpdate(); return null; } }); } }