/* * Copyright 2004-2009 the original author or authors. * * 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.compass.needle.gigaspaces.service; import com.gigaspaces.events.NotifyActionType; import com.gigaspaces.events.batching.BatchRemoteEvent; import com.j_spaces.core.client.EntryArrivedRemoteEvent; import org.compass.core.Compass; import org.compass.core.CompassCallbackWithoutResult; import org.compass.core.CompassException; import org.compass.core.CompassSession; import org.compass.core.CompassTemplate; import org.compass.core.mapping.Cascade; import org.compass.core.spi.InternalCompassSession; import org.openspaces.core.GigaSpace; import org.openspaces.events.SpaceDataEventListener; import org.springframework.transaction.TransactionStatus; /** * A space data event listener that should be registered with a notify container (probably with all its notify flag * set: write, update, take, and lease expiration). Using the provided event it either index the given object * (if it is a write or an update) or deletes it from the index (if it is a take or lease expiration). * * <p>The Compass instance is passed, probably configured to store the index on the Space it listens for * notificaitons on in a collocated manner. * * <p>Note, batching should probably be used to increase indexing perfomance. * * @author kimchy */ public class CompassIndexEventListener implements SpaceDataEventListener { private CompassTemplate compassTemplate; public CompassIndexEventListener(Compass compass) { this.compassTemplate = new CompassTemplate(compass); } public void onEvent(final Object event, final GigaSpace gigaSpace, final TransactionStatus transactionStatus, final Object source) { if (event instanceof Object[]) { final Object[] events = (Object[]) event; final BatchRemoteEvent batchRemoteEvent = (BatchRemoteEvent) source; compassTemplate.execute(new CompassCallbackWithoutResult() { protected void doInCompassWithoutResult(CompassSession session) throws CompassException { for (int i = 0; i < events.length; i++) { performOperation(session, events[i], (EntryArrivedRemoteEvent) batchRemoteEvent.getEvents()[i]); } } }); } else { final EntryArrivedRemoteEvent remoteEvent = (EntryArrivedRemoteEvent) source; compassTemplate.execute(new CompassCallbackWithoutResult() { protected void doInCompassWithoutResult(CompassSession session) throws CompassException { performOperation(session, event, remoteEvent); } }); } } private void performOperation(CompassSession session, Object event, EntryArrivedRemoteEvent remoteEvent) { if (remoteEvent.getNotifyActionType() == NotifyActionType.NOTIFY_LEASE_EXPIRATION || remoteEvent.getNotifyActionType() == NotifyActionType.NOTIFY_TAKE) { if (((InternalCompassSession) session).getMapping().hasMappingForClass(event.getClass(), Cascade.DELETE)) { session.delete(event); } } else if (remoteEvent.getNotifyActionType() == NotifyActionType.NOTIFY_UPDATE || remoteEvent.getNotifyActionType() == NotifyActionType.NOTIFY_WRITE) { if (((InternalCompassSession) session).getMapping().hasMappingForClass(event.getClass(), Cascade.SAVE)) { session.save(event); } } } }