/*
*------------------------------------------------------------------------------
* Copyright (C) 2015-2016 University of Dundee. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*------------------------------------------------------------------------------
*/
package omero.gateway.facility;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import ome.util.search.LuceneQueryBuilder;
import omero.ApiUsageException;
import omero.InternalException;
import omero.api.SearchPrx;
import omero.gateway.Gateway;
import omero.gateway.SecurityContext;
import omero.gateway.exception.DSAccessException;
import omero.gateway.exception.DSOutOfServiceException;
import omero.gateway.model.SearchParameters;
import omero.gateway.model.SearchResult;
import omero.gateway.model.SearchResultCollection;
import omero.gateway.model.SearchScope;
import omero.model.Details;
import omero.model.DetailsI;
import omero.model.Experimenter;
import omero.model.IObject;
import omero.gateway.model.DataObject;
import omero.gateway.model.PlateAcquisitionData;
import omero.gateway.model.PlateData;
import omero.gateway.util.PojoMapper;
/**
* A {@link Facility} for performing searches
* @author Dominik Lindner <a
* href="mailto:d.lindner@dundee.ac.uk">d.lindner@dundee.ac.uk</a>
* @since 5.1
*/
public class SearchFacility extends Facility {
/** Reference to the {@link BrowseFacility} */
private BrowseFacility browse;
/**
* Creates a new instance
* @param gateway Reference to the {@link Gateway}
*/
SearchFacility(Gateway gateway) throws ExecutionException {
super(gateway);
this.browse = gateway.getFacility(BrowseFacility.class);
}
/**
* Searches for data.
*
* @param ctx
* The security context.
* @param context
* The context of search (if context.groupId == -1 the scope of
* the search will be all groups, otherwise the scope of the
* search will be the group set in the security context)
* @return The found objects.
* @throws DSOutOfServiceException
* If the connection is broken, or not logged in
* @throws DSAccessException
* If an error occurred while trying to retrieve data from OMERO
* service.
*/
public SearchResultCollection search(SecurityContext ctx, SearchParameters context)
throws DSOutOfServiceException, DSAccessException {
SearchResultCollection result = new SearchResultCollection();
if (context.getTypes().isEmpty()) {
return result;
}
SearchPrx service = gateway.getSearchService(ctx);
int batchSize = context.getTypes().size() == 1 ? 1000 : context
.getTypes().size() * 500;
// if search for Plates automatically include Plate Runs
if (context.getTypes().contains(PlateData.class))
context.getTypes().add(PlateAcquisitionData.class);
for (Class<? extends DataObject> type : context.getTypes()) {
try {
// set general parameters
service.clearQueries();
service.setAllowLeadingWildcard(true);
service.setCaseSentivice(false);
String searchForClass = PojoMapper.convertTypeForSearch(type);
service.onlyType(searchForClass);
service.setBatchSize(batchSize);
// set the owner/group restriction
if (context.getUserId() >= 0) {
Details ownerRestriction = new DetailsI();
Experimenter exp = (Experimenter) browse.findIObject(ctx,
Experimenter.class.getName(), context.getUserId());
ownerRestriction.setOwner(exp);
service.onlyOwnedBy(ownerRestriction);
}
// set time
Date from = null;
Date to = null;
String dateType = null;
if (context.getDateType() != -1) {
Timestamp start = context.getStart();
Timestamp end = context.getEnd();
from = start != null ? new Date(start.getTime()) : null;
to = end != null ? new Date(end.getTime()) : null;
if (context.getDateType() == SearchParameters.DATE_ACQUISITION)
dateType = LuceneQueryBuilder.DATE_ACQUISITION;
else
dateType = LuceneQueryBuilder.DATE_IMPORT;
}
Map<String, String> m = new HashMap<String, String>();
if (context.getGroupId() == SearchParameters.ALL_GROUPS_ID) {
m.put("omero.group", "-1");
} else {
m.put("omero.group", "" + ctx.getGroupID());
}
DateFormat df = new SimpleDateFormat("yyyyMMdd");
String fields = SearchScope.getStringRepresentation(context.getScope());
String dFrom = from != null ? df.format(from) : null;
String dTo = to != null ? df.format(to) : null;
try {
service.byLuceneQueryBuilder(fields, dFrom, dTo, dateType,
context.getQuery(), m);
} catch (ApiUsageException e) {
result.setError(SearchResultCollection.GENERAL_ERROR);
return result;
}
try {
if (service.hasNext(m)) {
List<IObject> l = service.results(m);
Iterator<IObject> k = l.iterator();
IObject object;
while (k.hasNext()) {
object = k.next();
if (searchForClass.equals(object.getClass()
.getName())) {
SearchResult sr = new SearchResult();
sr.setObject(PojoMapper.asDataObject(object));
if (!result.contains(sr))
result.add(sr);
}
}
}
} catch (Exception e) {
if (e instanceof InternalException) {
if (e.toString().contains("TooManyClauses"))
result.setError(SearchResultCollection.TOO_MANY_CLAUSES);
else
result.setError(SearchResultCollection.GENERAL_ERROR);
} else {
result.setError(SearchResultCollection.TOO_MANY_RESULTS_ERROR);
}
gateway.closeService(ctx, service);
return result;
}
service.clearQueries();
} catch (Throwable e) {
handleException(this, e, "Could not load hierarchy");
}
}
if (service != null)
gateway.closeService(ctx, service);
return result;
}
}