Index: data/ibatis/src/main/resources/applicationContext-dao.xml
===================================================================
--- data/ibatis/src/main/resources/applicationContext-dao.xml	(revision 3196)
+++ data/ibatis/src/main/resources/applicationContext-dao.xml	Mon Jan 05 00:43:18 IST 2009
@@ -1,10 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
             http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
        default-lazy-init="true">
-    
+
     <!-- SqlMap setup for iBATIS Database Layer -->
     <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
         <property name="configLocation" value="classpath:/sql-map-config.xml"/>
@@ -21,4 +23,64 @@
 
     <!-- Activates scanning of @Repository -->
     <context:component-scan base-package="org.appfuse.dao"/>
+
+    <!-- Compass Search Section -->
+
+    <!-- Compass Bean, automatically scanning for searchable classes within the model -->
+    <!-- Hooks into Spring transaction management and stores the index on the file system -->
+    <bean id="compass" class="org.compass.spring.LocalCompassBean">
+        <property name="mappingScan" value="org.appfuse.model"/>
+        <property name="transactionManager" ref="transactionManager"/>
+        <property name="settings">
+            <map>
+                <entry key="compass.engine.connection" value="target/test-index"/>
+            </map>
+        </property>
+    </bean>
+
+    <!-- Compass Template allowing to automatically join/start exising transactions when performing operations -->
+    <bean id="compassTemplate" class="org.compass.core.CompassTemplate">
+        <property name="compass" ref="compass"/>
+    </bean>
+
+    <!-- Compass Search Helper allowing to perform search operations in a simpler manner -->
+    <bean id="compassSearchHelper" class="org.compass.core.support.search.CompassSearchHelper">
+        <constructor-arg ref="compass"/>
+        <property name="pageSize" value="10"/>
+    </bean>
+
+    <!-- CompassGps allows to perform index operation based on the select statements defined in iBatis -->
+    <bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop">
+        <property name="compass" ref="compass"/>
+        <property name="gpsDevices">
+            <list>
+                <bean class="org.compass.gps.device.ibatis.SqlMapClientGpsDevice">
+                    <property name="name" value="ibatis"/>
+                    <property name="sqlMapClient" ref="sqlMapClient"/>
+                    <property name="selectStatementsIds">
+                        <list>
+                            <value>getUsers</value>
+                        </list>
+                    </property>
+                </bean>
+            </list>
+        </property>
+    </bean>
+
+    <!-- Search AOP section allows to intercept operations and apply them to the index -->
+    <bean id="compassSearchSaveAdvice" class="org.appfuse.dao.ibatis.search.CompassSaveAdvice">
+        <property name="compass" ref="compass" />
+    </bean>
+    <bean id="compassSearchDeleteAdvice" class="org.appfuse.dao.ibatis.search.CompassDeleteAdvice">
+        <property name="compass" ref="compass" />
+    </bean>
+
+    <aop:config>
+        <aop:pointcut id="searchSave" expression="execution(* org.appfuse.dao.ibatis.*.save*(..))"/>
+        <aop:pointcut id="searchDelete" expression="execution(* org.appfuse.dao.ibatis.*.remove*(..))"/>
+
+        <aop:advisor pointcut-ref="searchSave" advice-ref="compassSearchSaveAdvice"/>
+        <aop:advisor pointcut-ref="searchDelete" advice-ref="compassSearchDeleteAdvice"/>
+    </aop:config>
+
 </beans>
Index: data/jpa/src/test/resources/log4j.xml
===================================================================
--- data/jpa/src/test/resources/log4j.xml	(revision 3196)
+++ data/jpa/src/test/resources/log4j.xml	Sun Jan 04 23:22:26 IST 2009
@@ -14,6 +14,10 @@
         <level value="WARN"/>
     </logger>
 
+    <logger name="org.compass">
+        <level value="WARN"/>
+    </logger>
+    
     <logger name="org.hibernate">
         <level value="WARN"/>
     </logger>
Index: data/hibernate/src/test/resources/log4j.xml
===================================================================
--- data/hibernate/src/test/resources/log4j.xml	(revision 3196)
+++ data/hibernate/src/test/resources/log4j.xml	Sun Jan 04 22:17:18 IST 2009
@@ -14,6 +14,10 @@
         <level value="WARN"/>
     </logger>
 
+    <logger name="org.compass">
+        <level value="WARN"/>
+    </logger>
+
     <logger name="org.hibernate">
         <level value="WARN"/>
     </logger>
Index: data/common/src/main/java/org/appfuse/model/Address.java
===================================================================
--- data/common/src/main/java/org/appfuse/model/Address.java	(revision 3196)
+++ data/common/src/main/java/org/appfuse/model/Address.java	Sun Jan 04 21:04:13 IST 2009
@@ -7,6 +7,8 @@
 
 import org.apache.commons.lang.builder.ToStringBuilder;
 import org.apache.commons.lang.builder.ToStringStyle;
+import org.compass.annotations.Searchable;
+import org.compass.annotations.SearchableProperty;
 
 /**
  * This class is used to represent an address with address,
@@ -15,6 +17,7 @@
  * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
  */
 @Embeddable
+@Searchable(root = false)
 public class Address extends BaseObject implements Serializable {
     private static final long serialVersionUID = 3617859655330969141L;
     private String address;
@@ -24,26 +27,31 @@
     private String postalCode;
 
     @Column(length=150)
+    @SearchableProperty
     public String getAddress() {
         return address;
     }
 
     @Column(length=50)
+    @SearchableProperty
     public String getCity() {
         return city;
     }
 
     @Column(length=100)
+    @SearchableProperty
     public String getProvince() {
         return province;
     }
 
     @Column(length=100)
+    @SearchableProperty
     public String getCountry() {
         return country;
     }
 
     @Column(name="postal_code",length=15)
+    @SearchableProperty
     public String getPostalCode() {
         return postalCode;
     }
Index: data/common/src/main/java/org/appfuse/model/User.java
===================================================================
--- data/common/src/main/java/org/appfuse/model/User.java	(revision 3196)
+++ data/common/src/main/java/org/appfuse/model/User.java	Sun Jan 04 21:03:47 IST 2009
@@ -4,6 +4,10 @@
 import org.springframework.security.userdetails.UserDetails;
 import org.apache.commons.lang.builder.ToStringBuilder;
 import org.apache.commons.lang.builder.ToStringStyle;
+import org.compass.annotations.Searchable;
+import org.compass.annotations.SearchableId;
+import org.compass.annotations.SearchableProperty;
+import org.compass.annotations.SearchableComponent;
 
 import javax.persistence.*;
 import java.io.Serializable;
@@ -23,6 +27,7 @@
  */
 @Entity
 @Table(name="app_user")
+@Searchable
 public class User extends BaseObject implements Serializable, UserDetails {
     private static final long serialVersionUID = 3832626162173359411L;
 
@@ -58,11 +63,13 @@
     }
 
     @Id @GeneratedValue(strategy=GenerationType.AUTO)
+    @SearchableId
     public Long getId() {
         return id;
     }
 
     @Column(nullable=false,length=50,unique=true)
+    @SearchableProperty
     public String getUsername() {
         return username;
     }
@@ -83,25 +90,30 @@
     }
 
     @Column(name="first_name",nullable=false,length=50)
+    @SearchableProperty
     public String getFirstName() {
         return firstName;
     }
 
     @Column(name="last_name",nullable=false,length=50)
+    @SearchableProperty
     public String getLastName() {
         return lastName;
     }
 
     @Column(nullable=false,unique=true)
+    @SearchableProperty
     public String getEmail() {
         return email;
     }
 
     @Column(name="phone_number")
+    @SearchableProperty
     public String getPhoneNumber() {
         return phoneNumber;
     }
 
+    @SearchableProperty
     public String getWebsite() {
         return website;
     }
@@ -116,6 +128,7 @@
     }
 
     @Embedded
+    @SearchableComponent
     public Address getAddress() {
         return address;
     }
Index: data/ibatis/src/test/java/org/appfuse/dao/UserDaoTest.java
===================================================================
--- data/ibatis/src/test/java/org/appfuse/dao/UserDaoTest.java	(revision 3196)
+++ data/ibatis/src/test/java/org/appfuse/dao/UserDaoTest.java	Sun Jan 04 23:44:01 IST 2009
@@ -9,13 +9,20 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.annotation.ExpectedException;
 import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
 import org.junit.Test;
+import org.compass.core.*;
+import org.compass.gps.CompassGps;
 
 public class UserDaoTest extends BaseDaoTestCase {
     @Autowired
     private UserDao dao;
     @Autowired
     private RoleDao rdao;
+    @Autowired
+    private CompassTemplate compassTemplate;
+    @Autowired
+    private CompassGps compassGps;
 
     @Test
     @ExpectedException(DataAccessException.class)
@@ -123,4 +130,43 @@
         boolean b = dao.exists(111L);
         assertFalse(b);
     }
+
+    @Test
+    public void testUserSearch() throws Exception {
+        // reindex all the data
+        compassGps.index();
+
+        User user = compassTemplate.get(User.class, -2);
+        assertNotNull(user);
+        assertEquals("Matt", user.getFirstName());
+
+        compassTemplate.execute(new CompassCallbackWithoutResult() {
+            @Override
+            protected void doInCompassWithoutResult(CompassSession compassSession) throws CompassException {
+                CompassHits hits = compassSession.find("Matt");
+                assertEquals(1, hits.length());
+                assertEquals("Matt", ((User) hits.data(0)).getFirstName());
+                assertEquals("Matt", hits.resource(0).getValue("firstName"));
-}
+            }
+        });
+
+        // test mirroring
+        user = dao.get(-2L);
+        user.setFirstName("MattX");
+        dao.saveUser(user);
+
+        // now verify it is reflected in the index
+        user = compassTemplate.get(User.class, -2);
+        assertNotNull(user);
+        assertEquals("MattX", user.getFirstName());
+
+        compassTemplate.execute(new CompassCallbackWithoutResult() {
+            @Override
+            protected void doInCompassWithoutResult(CompassSession compassSession) throws CompassException {
+                CompassHits hits = compassSession.find("MattX");
+                assertEquals(1, hits.length());
+                assertEquals("MattX", ((User) hits.data(0)).getFirstName());
+            }
+        });
+    }
+}
Index: data/ibatis/pom.xml
===================================================================
--- data/ibatis/pom.xml	(revision 3196)
+++ data/ibatis/pom.xml	Sun Jan 04 23:49:07 IST 2009
@@ -44,6 +44,42 @@
         <plugins>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
+                <artifactId>aspectj-maven-plugin</artifactId>
+                <version>1.0</version>
+                <configuration>
+                    <source>1.5</source>
+                    <verbose>true</verbose>
+                    <complianceLevel>1.5</complianceLevel>
+                    <showWeaveInfo>true</showWeaveInfo>
+                    <aspectLibraries>
+                        <aspectLibrary>
+                            <groupId>org.springframework</groupId>
+                            <artifactId>spring-aspects</artifactId>
+                        </aspectLibrary>
+                    </aspectLibraries>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.aspectj</groupId>
+                        <artifactId>aspectjrt</artifactId>
+                        <version>${aspectj.version}</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.aspectj</groupId>
+                        <artifactId>aspectjtools</artifactId>
+                        <version>${aspectj.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
                 <artifactId>dbunit-maven-plugin</artifactId>
                 <version>1.0-beta-1</version>
                 <configuration>
@@ -136,5 +172,25 @@
             <artifactId>ibatis-sqlmap</artifactId>
             <version>${ibatis.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+            <version>${aspectj.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjrt</artifactId>
+            <version>${aspectj.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aop</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aspects</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
     </dependencies>
 </project>
Index: data/ibatis/src/test/resources/log4j.xml
===================================================================
--- data/ibatis/src/test/resources/log4j.xml	(revision 3196)
+++ data/ibatis/src/test/resources/log4j.xml	Sun Jan 04 23:43:01 IST 2009
@@ -14,6 +14,10 @@
         <level value="WARN"/>
     </logger>
 
+    <logger name="org.compass">
+        <level value="WARN"/>
+    </logger>
+
     <logger name="org.springframework">
         <level value="WARN"/>
     </logger>
Index: data/ibatis/src/main/java/org/appfuse/dao/ibatis/search/CompassSaveAdvice.java
===================================================================
--- data/ibatis/src/main/java/org/appfuse/dao/ibatis/search/CompassSaveAdvice.java	Mon Jan 05 00:38:53 IST 2009
+++ data/ibatis/src/main/java/org/appfuse/dao/ibatis/search/CompassSaveAdvice.java	Mon Jan 05 00:38:53 IST 2009
@@ -0,0 +1,38 @@
+package org.appfuse.dao.ibatis.search;
+
+import org.appfuse.dao.ibatis.GenericDaoiBatis;
+import org.compass.core.mapping.CascadeMapping;
+import org.compass.core.mapping.CompassMapping;
+import org.compass.core.spi.InternalCompass;
+
+import java.lang.reflect.Method;
+
+/**
+ * An extension to Compass Save Advice that works only wiht {@link org.appfuse.dao.ibatis.GenericDaoiBatis}
+ * class (or sub classes) and uses its {@link org.appfuse.dao.ibatis.GenericDaoiBatis#getPersistentClass()}
+ * in order to know if the class can be saved/created in the index.
+ *
+ * @author kimchy
+ */
+public class CompassSaveAdvice extends org.compass.spring.aop.CompassSaveAdvice {
+
+    private CompassMapping compassMapping;
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        super.afterPropertiesSet();
+        compassMapping = ((InternalCompass) compassTemplate.getCompass()).getMapping();
+    }
+
+    @Override
+    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
+        if (!(target instanceof GenericDaoiBatis)) {
+            return;
+        }
+        Class persistentClass = ((GenericDaoiBatis) target).getPersistentClass();
+        if (compassMapping.hasMappingForClass(persistentClass, CascadeMapping.Cascade.SAVE) ||
+                compassMapping.hasMappingForClass(persistentClass, CascadeMapping.Cascade.CREATE)) {
+            compassTemplate.save(findObject(returnValue, args));
+        }
+    }
+}
\ No newline at end of file
Index: data/jpa/src/main/resources/applicationContext-dao.xml
===================================================================
--- data/jpa/src/main/resources/applicationContext-dao.xml	(revision 3196)
+++ data/jpa/src/main/resources/applicationContext-dao.xml	Mon Jan 05 00:45:15 IST 2009
@@ -44,4 +44,44 @@
 
     <!-- Activates scanning of @Repository -->
     <context:component-scan base-package="org.appfuse.dao"/>
+
+    <!-- Compass Search Section -->
+
+    <!-- Compass Bean, automatically scanning for searchable classes within the model -->
+    <!-- Hooks into Spring transaction management and stores the index on the file system -->
+    <bean id="compass" class="org.compass.spring.LocalCompassBean">
+        <property name="mappingScan" value="org.appfuse.model" />
+        <property name="transactionManager" ref="transactionManager" />
+        <property name="settings">
+            <map>
+                <entry key="compass.engine.connection" value="target/test-index" />
+            </map>
+        </property>
+    </bean>
+
+    <!-- Compass Template allowing to automatically join/start exising transactions when performing operations -->
+    <bean id="compassTemplate" class="org.compass.core.CompassTemplate">
+        <property name="compass" ref="compass" />
+    </bean>
+
+    <!-- Compass Search Helper allowing to perform search operations in a simpler manner -->
+    <bean id="compassSearchHelper" class="org.compass.core.support.search.CompassSearchHelper">
+        <constructor-arg ref="compass" />
+        <property name="pageSize" value="10" />
+    </bean>
+
+    <!-- CompassGps will automatically mirror any changes done thorugh JPA to searchable classes to the index -->
+    <!-- It will also provide the index operation allowing to reindex the database -->
+    <bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop">
+        <property name="compass" ref="compass" />
+        <property name="gpsDevices">
+            <list>
+                <bean class="org.compass.gps.device.jpa.JpaGpsDevice">
+                    <property name="name" value="jpa" />
+                    <property name="injectEntityLifecycleListener" value="true" />
+                    <property name="entityManagerFactory" ref="entityManagerFactory" />
+                </bean>
+            </list>
+        </property>
+    </bean>
 </beans>
Index: data/hibernate/src/test/java/org/appfuse/dao/UserDaoTest.java
===================================================================
--- data/hibernate/src/test/java/org/appfuse/dao/UserDaoTest.java	(revision 3196)
+++ data/hibernate/src/test/java/org/appfuse/dao/UserDaoTest.java	Sun Jan 04 22:42:25 IST 2009
@@ -11,12 +11,18 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.annotation.NotTransactional;
 import org.springframework.test.annotation.ExpectedException;
+import org.compass.core.*;
+import org.compass.gps.CompassGps;
 
 public class UserDaoTest extends BaseDaoTestCase {
     @Autowired
     private UserDao dao;
     @Autowired
     private RoleDao rdao;
+    @Autowired
+    private CompassTemplate compassTemplate;
+    @Autowired
+    private CompassGps compassGps;
 
     @Test
     @ExpectedException(DataAccessException.class)
@@ -139,4 +145,44 @@
         boolean b = dao.exists(111L);
         assertFalse(b);
     }
+
+    @Test
+    public void testUserSearch() throws Exception {
+        // reindex all the data
+        compassGps.index();
+
+        User user = compassTemplate.get(User.class, -2);
+        assertNotNull(user);
+        assertEquals("Matt", user.getFirstName());
+
+        compassTemplate.execute(new CompassCallbackWithoutResult() {
+            @Override
+            protected void doInCompassWithoutResult(CompassSession compassSession) throws CompassException {
+                CompassHits hits = compassSession.find("Matt");
+                assertEquals(1, hits.length());
+                assertEquals("Matt", ((User) hits.data(0)).getFirstName());
+                assertEquals("Matt", hits.resource(0).getValue("firstName"));
-}
+            }
+        });
+
+        // test mirroring
+        user = dao.get(-2L);
+        user.setFirstName("MattX");
+        dao.saveUser(user);
+        flush();
+
+        // now verify it is reflected in the index
+        user = compassTemplate.get(User.class, -2);
+        assertNotNull(user);
+        assertEquals("MattX", user.getFirstName());
+
+        compassTemplate.execute(new CompassCallbackWithoutResult() {
+            @Override
+            protected void doInCompassWithoutResult(CompassSession compassSession) throws CompassException {
+                CompassHits hits = compassSession.find("MattX");
+                assertEquals(1, hits.length());
+                assertEquals("MattX", ((User) hits.data(0)).getFirstName());
+            }
+        });
+    }
+}
Index: data/ibatis/src/main/java/org/appfuse/dao/ibatis/GenericDaoiBatis.java
===================================================================
--- data/ibatis/src/main/java/org/appfuse/dao/ibatis/GenericDaoiBatis.java	(revision 3196)
+++ data/ibatis/src/main/java/org/appfuse/dao/ibatis/GenericDaoiBatis.java	Sun Jan 04 23:57:07 IST 2009
@@ -90,6 +90,10 @@
         return this.sqlMapClientTemplate;
     }
 
+    public Class<T> getPersistentClass() {
+        return persistentClass;
+    }
+    
     /**
      * {@inheritDoc}
      */
Index: data/jpa/src/test/java/org/appfuse/dao/UserDaoTest.java
===================================================================
--- data/jpa/src/test/java/org/appfuse/dao/UserDaoTest.java	(revision 3196)
+++ data/jpa/src/test/java/org/appfuse/dao/UserDaoTest.java	Sun Jan 04 23:43:55 IST 2009
@@ -5,16 +5,31 @@
 import org.appfuse.model.Role;
 import org.appfuse.model.User;
 import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.orm.ObjectRetrievalFailureException;
 import org.springframework.test.annotation.ExpectedException;
+import org.springframework.test.annotation.NotTransactional;
+import org.compass.core.*;
+import org.compass.gps.CompassGps;
 
+import javax.persistence.PersistenceContext;
+import javax.persistence.EntityManager;
+import javax.persistence.FlushModeType;
+
 public class UserDaoTest extends BaseDaoTestCase {
+    @PersistenceContext
+    private EntityManager entityManager;
+    
     @Autowired
     private UserDao dao;
     @Autowired
     private RoleDao rdao;
+    @Autowired
+    private CompassTemplate compassTemplate;
+    @Autowired
+    private CompassGps compassGps;
 
     @Test
     @ExpectedException(ObjectRetrievalFailureException.class)
@@ -123,4 +138,45 @@
         boolean b = dao.exists(111L);
         assertFalse(b);
     }
+
+    @Test
+    public void testUserSearch() throws Exception {
+        // reindex all the data
+        compassGps.index();
+
+        User user = compassTemplate.get(User.class, -2);
+        assertNotNull(user);
+        assertEquals("Matt", user.getFirstName());
+
+        compassTemplate.execute(new CompassCallbackWithoutResult() {
+            @Override
+            protected void doInCompassWithoutResult(CompassSession compassSession) throws CompassException {
+                CompassHits hits = compassSession.find("Matt");
+                assertEquals(1, hits.length());
+                assertEquals("Matt", ((User) hits.data(0)).getFirstName());
+                assertEquals("Matt", hits.resource(0).getValue("firstName"));
-}
+            }
+        });
+
+        // test mirroring
+        user = dao.get(-2L);
+        user.setFirstName("MattX");
+        dao.saveUser(user);
+        entityManager.flush();
+        entityManager.clear();
+
+        // now verify it is reflected in the index
+        user = compassTemplate.get(User.class, -2);
+        assertNotNull(user);
+        assertEquals("MattX", user.getFirstName());
+
+        compassTemplate.execute(new CompassCallbackWithoutResult() {
+            @Override
+            protected void doInCompassWithoutResult(CompassSession compassSession) throws CompassException {
+                CompassHits hits = compassSession.find("MattX");
+                assertEquals(1, hits.length());
+                assertEquals("MattX", ((User) hits.data(0)).getFirstName());
+            }
+        });
+    }
+}
Index: data/ibatis/src/main/java/org/appfuse/dao/ibatis/search/CompassDeleteAdvice.java
===================================================================
--- data/ibatis/src/main/java/org/appfuse/dao/ibatis/search/CompassDeleteAdvice.java	Mon Jan 05 00:38:32 IST 2009
+++ data/ibatis/src/main/java/org/appfuse/dao/ibatis/search/CompassDeleteAdvice.java	Mon Jan 05 00:38:32 IST 2009
@@ -0,0 +1,37 @@
+package org.appfuse.dao.ibatis.search;
+
+import org.appfuse.dao.ibatis.GenericDaoiBatis;
+import org.compass.core.spi.InternalCompass;
+import org.compass.core.mapping.CascadeMapping;
+import org.compass.core.mapping.CompassMapping;
+
+import java.lang.reflect.Method;
+
+/**
+ * An extension to Compass Delete Advice that works only wiht {@link org.appfuse.dao.ibatis.GenericDaoiBatis}
+ * class (or sub classes) and uses its {@link org.appfuse.dao.ibatis.GenericDaoiBatis#getPersistentClass()}
+ * in order to know which class to delete from the index based on its PK.
+ *
+ * @author kimchy
+ */
+public class CompassDeleteAdvice extends org.compass.spring.aop.CompassDeleteAdvice {
+
+    private CompassMapping compassMapping;
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        super.afterPropertiesSet();
+        compassMapping = ((InternalCompass) compassTemplate.getCompass()).getMapping();
+    }
+    
+    @Override
+    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
+        if (!(target instanceof GenericDaoiBatis)) {
+            return;
+        }
+        Class persistentClass = ((GenericDaoiBatis) target).getPersistentClass();
+        if (compassMapping.hasMappingForClass(persistentClass, CascadeMapping.Cascade.DELETE)) {
+            compassTemplate.delete(persistentClass, findObject(returnValue, args));
+        }
+    }
+}
Index: data/hibernate/src/main/resources/applicationContext-dao.xml
===================================================================
--- data/hibernate/src/main/resources/applicationContext-dao.xml	(revision 3196)
+++ data/hibernate/src/main/resources/applicationContext-dao.xml	Mon Jan 05 00:45:15 IST 2009
@@ -34,4 +34,42 @@
     <!-- Activates scanning of @Repository -->
     <context:component-scan base-package="org.appfuse.dao"/>
 
+    <!-- Compass Search Section -->
+
+    <!-- Compass Bean, automatically scanning for searchable classes within the model -->
+    <!-- Hooks into Spring transaction management and stores the index on the file system -->
+    <bean id="compass" class="org.compass.spring.LocalCompassBean">
+        <property name="mappingScan" value="org.appfuse.model" />
+        <property name="transactionManager" ref="transactionManager" />
+        <property name="settings">
+            <map>
+                <entry key="compass.engine.connection" value="target/test-index" />
+            </map>
+        </property>
+    </bean>
+
+    <!-- Compass Template allowing to automatically join/start exising transactions when performing operations -->
+    <bean id="compassTemplate" class="org.compass.core.CompassTemplate">
+        <property name="compass" ref="compass" />
+    </bean>
+
+    <!-- Compass Search Helper allowing to perform search operations in a simpler manner -->
+    <bean id="compassSearchHelper" class="org.compass.core.support.search.CompassSearchHelper">
+        <constructor-arg ref="compass" />
+        <property name="pageSize" value="10" />
+    </bean>
+
+    <!-- CompassGps will automatically mirror any changes done thorugh Hibernate to searchable classes to the index -->
+    <!-- It will also provide the index operation allowing to reindex the database -->
+    <bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop">
+        <property name="compass" ref="compass" />
+        <property name="gpsDevices">
+            <list>
+                <bean class="org.compass.gps.device.hibernate.HibernateGpsDevice">
+                    <property name="name" value="hibernate" />
+                    <property name="sessionFactory" ref="sessionFactory" />
+                </bean>
+            </list>
+        </property>
+    </bean>
 </beans>
Index: pom.xml
===================================================================
--- pom.xml	(revision 3196)
+++ pom.xml	Mon Jan 05 00:29:59 IST 2009
@@ -253,6 +253,13 @@
                 <enabled>true</enabled>
             </snapshots>
         </repository>
+        <repository>
+            <id>compass</id>
+            <url>http://repo.compass-project.org</url>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
     </repositories>
 
     <pluginRepositories>
@@ -478,6 +485,7 @@
         <commons.dbcp.version>1.2.1</commons.dbcp.version>
         <commons.fileupload.version>1.2.1</commons.fileupload.version>
         <commons.io.version>1.3.2</commons.io.version>
+        <compass.version>2.1.0</compass.version>
         <corejsf.validator.version>1.0</corejsf.validator.version>
         <displaytag.version>1.1.1</displaytag.version>
         <dwr.version>2.0.1</dwr.version>
@@ -487,7 +495,7 @@
         <hibernate.version>3.3.1.GA</hibernate.version>
         <hibernate.annotations.version>3.4.0.GA</hibernate.annotations.version>
         <hibernate.entitymanager.version>3.4.0.GA</hibernate.entitymanager.version>
-        <ibatis.version>2.3.0</ibatis.version>
+        <ibatis.version>2.3.4.726</ibatis.version>
         <javamail.version>1.4</javamail.version>
         <jmock.version>2.4.0</jmock.version>
         <jpa.version>1.0</jpa.version>
Index: data/common/pom.xml
===================================================================
--- data/common/pom.xml	(revision 3196)
+++ data/common/pom.xml	Sun Jan 04 20:16:32 IST 2009
@@ -50,6 +50,11 @@
             <artifactId>persistence-api</artifactId>
             <version>${jpa.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.compass-project</groupId>
+            <artifactId>compass</artifactId>
+            <version>${compass.version}</version>
+        </dependency>
     </dependencies>
 </project>
 
