blob: a1b162d373d5de751761dc795a00af02ec598f5f [file] [log] [blame]
/*
* 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.usergrid.persistence;
import org.apache.usergrid.persistence.entities.Group;
import org.apache.usergrid.persistence.entities.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Iterator;
public class NotificationGraphIterator implements ResultsIterator, Iterable {
private static final Logger logger = LoggerFactory.getLogger(NotificationGraphIterator.class);
EntityManager entityManager;
private Iterator<EntityRef> source;
private Query query;
private Iterator currentIterator;
public NotificationGraphIterator(EntityManager entityManager,
Iterator<EntityRef> source,
Query query) {
this.entityManager = entityManager;
this.source = source;
this.query = query;
}
@Override
public Iterator iterator() {
return this;
}
@Override
public boolean hasNext() {
if (source == null) {
return false;
}
if (currentIterator != null && currentIterator.hasNext()) {
return true;
}
while (source.hasNext()) {
Object next = source.next();
Results r;
EntityRef ref = (EntityRef) next;
r = getResultsFor(ref);
if (r.size() > 0) {
if(ref.getType().equals(Group.ENTITY_TYPE)) {
currentIterator = new PagingResultsIterator(r, query.getResultsLevel(), Query.Level.REFS);
}else{
currentIterator = new PagingResultsIterator(r, query.getResultsLevel(), null);
}
return currentIterator.hasNext();
}
}
currentIterator = null;
source = null;
return false;
}
@Override
public Object next() {
return (currentIterator != null) ? currentIterator.next() : null;
}
@Override
public boolean hasPages() {
return currentIterator != null && currentIterator instanceof ResultsIterator && ((ResultsIterator) currentIterator).hasPages();
}
private Results getResultsFor(EntityRef ref) {
try {
query.setLimit(Query.MAX_LIMIT); // always fetch our MAX limit to reduce # of IO hops
if (query.getCollection() != null) {
// make sure this results in graph traversal
query.setQl("select *");
if(logger.isTraceEnabled()) {
logger.trace("Fetching with refType: {}, collection: {} with no query",
ref.getType(), query.getCollection());
}
// if we're fetching devices through groups->users->devices, get only the IDs and don't load the entities
if( ref.getType().equals(Group.ENTITY_TYPE)){
// groups->users is a passthrough to devices, load our max limit
query.setLimit(Query.MAX_LIMIT);
// set the query level for the when fetching users to IDS, we don't need the full entity
query.setResultsLevel(Query.Level.IDS);
return entityManager.searchCollection(ref, "users", query);
}
if( ref.getType().equals(User.ENTITY_TYPE)){
Query devicesQuery = new Query();
devicesQuery.setCollection("devices");
devicesQuery.setResultsLevel(Query.Level.CORE_PROPERTIES);
return entityManager.searchCollection(ref, devicesQuery.getCollection(), devicesQuery);
}
return entityManager.searchCollection(ref, query.getCollection(), query);
} else {
if(logger.isTraceEnabled()) {
logger.trace("Searching target entities with refType: {} for collection: {} with no query",
ref.getType(), query.getCollection());
}
query.setQl("select *"); // make sure this results in graph traversal
return entityManager.searchTargetEntities(ref, query);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}