| /* |
| * 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); |
| } |
| } |
| |
| } |