/*
* Copyright 2009 Niclas Hedhman.
*
* Licensed 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.qi4j.index.reindexer.internal;
import java.util.ArrayList;
import org.qi4j.api.common.QualifiedName;
import org.qi4j.api.configuration.Configuration;
import org.qi4j.api.entity.Identity;
import org.qi4j.api.injection.scope.Service;
import org.qi4j.api.injection.scope.Structure;
import org.qi4j.api.injection.scope.This;
import org.qi4j.api.service.ServiceReference;
import org.qi4j.api.structure.Module;
import org.qi4j.index.reindexer.Reindexer;
import org.qi4j.index.reindexer.ReindexerConfiguration;
import org.qi4j.io.Output;
import org.qi4j.io.Receiver;
import org.qi4j.io.Sender;
import org.qi4j.spi.entity.EntityState;
import org.qi4j.spi.entitystore.EntityStore;
import org.qi4j.spi.entitystore.StateChangeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ReindexerMixin
implements Reindexer
{
private static QualifiedName identityQN;
static
{
try
{
identityQN = QualifiedName.fromAccessor( Identity.class.getMethod( "identity" ) );
} catch (NoSuchMethodException e)
{
throw new InternalError("Qi4j Core Runtime codebase is corrupted. Contact Qi4j team: ReindexerMixin");
}
}
@This
private Configuration<ReindexerConfiguration> configuration;
@Service
private EntityStore store;
@Service
private Iterable<ServiceReference<StateChangeListener>> listeners;
@Structure
private Module module;
private Logger logger = LoggerFactory.getLogger(Reindexer.class);
@Override
public void reindex()
{
configuration.refresh();
ReindexerConfiguration conf = configuration.get();
Integer loadValue = conf.loadValue().get();
if (loadValue == null)
{
loadValue = 50;
}
new ReindexerOutput(loadValue).reindex(store);
}
private class ReindexerOutput
implements Output<EntityState, RuntimeException>, Receiver<EntityState, RuntimeException>
{
private int count;
private int loadValue;
private ArrayList<EntityState> states;
public ReindexerOutput(Integer loadValue)
{
this.loadValue = loadValue;
states = new ArrayList<EntityState>();
}
public void reindex(EntityStore store)
{
store.entityStates(module).transferTo(this);
reindexState();
}
@Override
public <SenderThrowableType extends Throwable> void receiveFrom(Sender<? extends EntityState, SenderThrowableType> sender) throws RuntimeException, SenderThrowableType
{
sender.sendTo(this);
reindexState();
}
@Override
public void receive(EntityState item)
throws RuntimeException
{
count++;
item.setPropertyValue( identityQN, item.identity().identity() );
states.add(item);
if (states.size() >= loadValue)
{
reindexState();
}
}
public void reindexState()
{
for (ServiceReference<StateChangeListener> listener : listeners)
{
listener.get().notifyChanges(states);
}
states.clear();
logger.debug("Reindexed " + count + " entities");
}
}
}