/* * #%L * server * %% * Copyright (C) 2012 - 2015 valdasraps * %% * 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 General Lesser Public License for more details. * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * <http://www.gnu.org/licenses/lgpl-3.0.html>. * #L% */ package lt.emasina.resthub.server.exporter; import javax.inject.Inject; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j; import lt.emasina.resthub.factory.ConnectionManager; import lt.emasina.resthub.server.cache.CcBase; import lt.emasina.resthub.server.exception.ServerErrorException; import lt.emasina.resthub.server.factory.DataFactory; import lt.emasina.resthub.server.factory.QueryFactory; import lt.emasina.resthub.server.handler.Handler; import lt.emasina.resthub.server.query.QueryStats; import org.hibernate.Session; import org.hibernate.Transaction; import org.restlet.resource.ResourceException; /** * DataExporter class * @author valdo * @param <C> */ @Log4j @Getter @RequiredArgsConstructor public abstract class Exporter <C extends CcBase<?>> { @Inject private ConnectionManager cm; @Inject private DataFactory df; @Inject private QueryFactory qf; private final Handler<C,?> handler; private volatile C value = null; public C getValue() { setValue(Boolean.TRUE); return value; } public void refreshValue() { setValue(Boolean.FALSE); } private void setValue(boolean useCache) { Integer id = handler.getId(); if (useCache && value != null) { if (log.isDebugEnabled()) { log.debug(String.format("got value from class property, 1LC (%d)", id)); } return; } QueryStats stats = handler.getQuery().getStats(); synchronized(this) { if (useCache && value != null) { if (log.isDebugEnabled()) { log.debug(String.format("got value from class property after lock, 1LC (%d)", id)); } } else { if (useCache) { value = handler.getCached(); } if (useCache && value != null) { stats.setCached(); if (log.isDebugEnabled()) { log.debug(String.format("got value from cache, 2LC (%d)", id)); } } else { long startTime = System.currentTimeMillis(); Session session = cm.getSession(handler.getQuery().getConnectionName()); Transaction tr = session.beginTransaction(); try { value = retrieveData(session); } catch (Exception ex) { stats.setSqlError(); if (ResourceException.class.isAssignableFrom(ex.getClass())) { throw (ResourceException) ex; } else { throw new ServerErrorException(ex); } } finally { tr.commit(); session.close(); } Long elapsed = System.currentTimeMillis() - startTime; stats.setSqlSuccess(elapsed.intValue()); stats.setCacheTime(elapsed); if (log.isDebugEnabled()) { log.debug(String.format("got value from database (%d), time: (%d)", id, elapsed)); } handler.setCached(value); } qf.removeExporter(handler); } } } protected abstract C retrieveData(Session session) throws Exception; }