/** * AnalyzerBeans * Copyright (C) 2014 Neopost - Customer Information Management * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * 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 distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.eobjects.analyzer.reference; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eobjects.analyzer.connection.Datastore; import org.eobjects.analyzer.connection.DatastoreConnection; import org.eobjects.analyzer.util.CollectionUtils2; import org.apache.metamodel.DataContext; import org.apache.metamodel.data.DataSet; import org.apache.metamodel.data.Row; import org.apache.metamodel.query.Query; import org.apache.metamodel.schema.Column; import org.apache.metamodel.util.BaseObject; import com.google.common.cache.Cache; /** * Reference values implementation based on a datastore column. * * */ public final class DatastoreReferenceValues extends BaseObject implements ReferenceValues<String> { private final Datastore _datastore; private final Column _column; private transient Cache<String, Boolean> _containsValueCache = CollectionUtils2.createCache(1000, 60); public DatastoreReferenceValues(Datastore datastore, Column column) { _datastore = datastore; _column = column; } @Override protected void decorateIdentity(List<Object> identifiers) { identifiers.add(_datastore); identifiers.add(_column); } public void clearCache() { _containsValueCache.invalidateAll(); } @Override public boolean containsValue(String value) { Boolean result = _containsValueCache.getIfPresent(value); if (result == null) { synchronized (_containsValueCache) { result = _containsValueCache.getIfPresent(value); if (result == null) { result = false; try (DatastoreConnection con = _datastore.openConnection()) { DataContext dataContext = con.getDataContext(); Query q = dataContext.query().from(_column.getTable()).selectCount().where(_column).eq(value) .toQuery(); try (DataSet dataSet = dataContext.executeQuery(q)) { if (dataSet.next()) { Row row = dataSet.getRow(); if (row != null) { Number count = (Number) row.getValue(0); if (count != null && count.intValue() > 0) { result = true; } assert !dataSet.next(); } } } } _containsValueCache.put(value, result); } } } return result; } @Override public Collection<String> getValues() { try (final DatastoreConnection con = _datastore.openConnection()) { final DataContext dataContext = con.getDataContext(); final Query q = dataContext.query().from(_column.getTable()).select(_column).toQuery(); q.selectDistinct(); try (final DataSet dataSet = dataContext.executeQuery(q)) { final List<String> values = new ArrayList<String>(); while (dataSet.next()) { final Row row = dataSet.getRow(); Object value = row.getValue(0); if (value != null) { value = value.toString(); } values.add((String) value); } return values; } } } }