Index: contrib/gdata-server/webroot/WEB-INF/classes/lucenestorage.properties.xml =================================================================== --- contrib/gdata-server/webroot/WEB-INF/classes/lucenestorage.properties.xml (revision 413530) +++ contrib/gdata-server/webroot/WEB-INF/classes/lucenestorage.properties.xml (working copy) @@ -5,6 +5,7 @@ 20 20 20 +true /tmp/storage/ true false Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageModifier.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageModifier.java (revision 413530) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageModifier.java (working copy) @@ -1,247 +1,350 @@ -package org.apache.lucene.gdata.storage.lucenestorage; - -import java.io.IOException; -import java.util.Date; - -import junit.framework.TestCase; - -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.gdata.server.FeedNotFoundException; -import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; -import org.apache.lucene.gdata.server.registry.GDataServerRegistry; -import org.apache.lucene.gdata.server.registry.RegistryBuilder; -import org.apache.lucene.gdata.storage.StorageException; -import org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController; -import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper; -import org.apache.lucene.gdata.storage.lucenestorage.StorageModifier; -import org.apache.lucene.gdata.storage.lucenestorage.StorageQuery; -import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation; -import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.Term; -import org.apache.lucene.search.Hits; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.TermQuery; -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.RAMDirectory; - -import com.google.gdata.data.BaseEntry; -import com.google.gdata.data.DateTime; -import com.google.gdata.data.Entry; -import com.google.gdata.data.ExtensionProfile; -import com.google.gdata.data.Feed; -import com.google.gdata.data.PlainTextConstruct; -import com.google.gdata.data.TextConstruct; -import com.google.gdata.data.TextContent; -import com.google.gdata.util.ParseException; - -public class TestStorageModifier extends TestCase { - private StorageModifier modifier; - private int count = 1; - - private ExtensionProfile profile; - private Directory dir; - - - private static String feedId = "myFeed"; - - protected void setUp() throws Exception { - FeedInstanceConfigurator configurator = new FeedInstanceConfigurator(); - configurator.setFeedType(Feed.class); - configurator.setFeedId(feedId); - configurator.setExtensionProfileClass(ExtensionProfile.class); - GDataServerRegistry.getRegistry().registerFeed(configurator); - dir = new RAMDirectory(); - this.profile = new ExtensionProfile(); - IndexWriter writer; - - writer = new IndexWriter(dir,new StandardAnalyzer(),true); - writer.close(); - modifier = StorageCoreController.getStorageCoreController(dir).getStorageModifier(); - +package org.apache.lucene.gdata.storage.lucenestorage; + +import java.io.IOException; + +import junit.framework.TestCase; + +import org.apache.lucene.gdata.data.GDataUser; +import org.apache.lucene.gdata.server.registry.ComponentType; +import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; +import org.apache.lucene.gdata.server.registry.GDataServerRegistry; +import org.apache.lucene.gdata.storage.StorageController; +import org.apache.lucene.gdata.storage.StorageException; +import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation; +import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.Hits; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.store.Directory; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.DateTime; +import com.google.gdata.data.Entry; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.data.Feed; +import com.google.gdata.data.PlainTextConstruct; +import com.google.gdata.data.TextContent; +import com.google.gdata.util.ParseException; + +public class TestStorageModifier extends TestCase { + private StorageModifier modifier; + + private int count = 1; + + private FeedInstanceConfigurator configurator; + + private Directory dir; + + private StorageCoreController controller; + + private static String feedId = "myFeed"; + + private static String username = "simon"; + + private static String password = "test"; + + protected void setUp() throws Exception { + GDataServerRegistry.getRegistry().registerComponent( + StorageCoreController.class); + this.configurator = new FeedInstanceConfigurator(); + this.configurator.setFeedType(Feed.class); + + this.configurator.setExtensionProfile(new ExtensionProfile()); + GDataServerRegistry.getRegistry().registerFeed(this.configurator); + + this.controller = (StorageCoreController) GDataServerRegistry + .getRegistry().lookup(StorageController.class, + ComponentType.STORAGECONTROLLER); + this.modifier = this.controller.getStorageModifier(); + this.dir = this.controller.getDirectory(); + + } + + protected void tearDown() throws Exception { + this.count = 1; + // destroy all resources + GDataServerRegistry.getRegistry().destroy();// TODO remove dependency + // here + + } + + /* + * Test method for + * 'org.apache.lucene.storage.lucenestorage.StorageModifier.updateEntry(StroageEntryWrapper)' + */ + public void testUpdateEntry() throws IOException, InterruptedException, + ParseException, StorageException { + testInsertEntry(); + for (int i = 1; i < this.count; i++) { + Entry e = new Entry(); + e.setId("" + i); + String insertString = "Hello world" + i; + e.setTitle(new PlainTextConstruct(insertString)); + StorageEntryWrapper wrapper = new StorageEntryWrapper(e, feedId, + StorageOperation.UPDATE, this.configurator); + this.modifier.updateEntry(wrapper); + ReferenceCounter innerQuery = this.controller + .getStorageQuery(); + BaseEntry fetchedEntry = innerQuery.get().singleEntryQuery("" + i, + feedId, this.configurator); + assertEquals("updated Title:", insertString, fetchedEntry + .getTitle().getPlainText()); + } + // double updates + for (int i = 1; i < this.count; i++) { + Entry e = new Entry(); + e.setId("" + i); + String insertString = "Hello world" + i; + e.setTitle(new PlainTextConstruct(insertString)); + StorageEntryWrapper wrapper = new StorageEntryWrapper(e, feedId, + StorageOperation.UPDATE, this.configurator); + this.modifier.updateEntry(wrapper); + + e = new Entry(); + e.setId("" + i); + insertString = "Foo Bar" + i; + e.setTitle(new PlainTextConstruct(insertString)); + wrapper = new StorageEntryWrapper(e, feedId, + StorageOperation.UPDATE, this.configurator); + this.modifier.updateEntry(wrapper); + + ReferenceCounter innerQuery = this.controller + .getStorageQuery(); + + BaseEntry fetchedEntry = innerQuery.get().singleEntryQuery("" + i, + feedId, this.configurator); + assertEquals("updated Title:", insertString, fetchedEntry + .getTitle().getPlainText()); + } + + } + + /* + * Test method for + * 'org.apache.lucene.storage.lucenestorage.StorageModifier.insertEntry(StroageEntryWrapper)' + */ + public void testInsertEntry() throws IOException, InterruptedException, + ParseException, StorageException { + + Thread a = getRunnerThread(this.count); + a.start(); + + Thread b = getRunnerThread((this.count += 10)); + b.start(); + a.join(); + for (int i = 1; i < this.count; i++) { + ReferenceCounter innerQuery = this.controller + .getStorageQuery(); + BaseEntry e = innerQuery.get().singleEntryQuery("" + i, feedId, + this.configurator); + assertEquals("get entry for id" + i, "" + i, e.getId()); + + } + b.join(); + ReferenceCounter query = this.controller + .getStorageQuery(); + + this.count += 10; + for (int i = 1; i < this.count; i++) { + BaseEntry e = query.get().singleEntryQuery("" + i, feedId, + this.configurator); + assertEquals("get entry for id" + i, "" + i, e.getId()); + } + + BaseEntry e = query.get().singleEntryQuery("" + this.count, feedId, + this.configurator); + assertNull("not entry for ID", e); + query.decrementRef(); + + } + + /* + * Test method for + * 'org.apache.lucene.storage.lucenestorage.StorageModifier.deleteEntry(String)' + */ + public void testDeleteEntry() throws IOException, InterruptedException, + ParseException, StorageException { + testInsertEntry(); + for (int i = 1; i < this.count; i++) { + if (i % 2 == 0 || i < 10) { + this.modifier.deleteEntry("" + i, feedId); + } + ReferenceCounter query = this.controller + .getStorageQuery(); + if (i % 2 == 0 || i < 10) { + assertNull(query.get().singleEntryQuery("" + i, feedId, + this.configurator)); + } else + assertEquals("" + i, query.get().singleEntryQuery("" + i, + feedId, this.configurator).getId()); + query.decrementRef(); + } + + this.controller.forceWrite(); + IndexSearcher searcher = new IndexSearcher(this.dir); + + for (int i = 1; i < this.count; i++) { + Query luceneQuery = new TermQuery(new Term( + StorageEntryWrapper.FIELD_ENTRY_ID, "" + i)); + Hits hits = searcher.search(luceneQuery); + if (i % 2 == 0 || i < 10) { + + assertEquals(0, hits.length()); + } else + assertEquals(1, hits.length()); + } + searcher.close(); + + } + + public void testSaveUser() throws StorageException, IOException { + + GDataUser user = new GDataUser(username); + user.setPassword(password); + StorageUserWrapper wrapper = new StorageUserWrapper(user); + this.modifier.createUser(wrapper); + IndexSearcher searcher = new IndexSearcher(this.dir); + Query q = new TermQuery(new Term(StorageUserWrapper.FIELD_USERNAME, + username)); + Hits h = searcher.search(q); + assertEquals("length == 1", 1, h.length()); + GDataUser storedUser = StorageUserWrapper.buildEntity(h.doc(0)); + assertTrue(storedUser.equals(user)); + searcher.close(); + } + + public void testDeleteUser() throws StorageException, IOException { + testSaveUser(); + this.modifier.deleteUser(username); + IndexSearcher searcher = new IndexSearcher(this.dir); + Query q = new TermQuery(new Term(StorageUserWrapper.FIELD_USERNAME, + username)); + Hits h = searcher.search(q); + assertEquals("length == 0", 0, h.length()); + searcher.close(); + } + + public void testUpdateUser() throws StorageException, IOException { + testSaveUser(); + GDataUser user = new GDataUser(username); + user.setPassword("newPass"); + StorageUserWrapper wrapper = new StorageUserWrapper(user); + this.modifier.updateUser(wrapper); + IndexSearcher searcher = new IndexSearcher(this.dir); + Query q = new TermQuery(new Term(StorageUserWrapper.FIELD_USERNAME, + username)); + Hits h = searcher.search(q); + assertEquals("length == 1", 1, h.length()); + GDataUser storedUser = StorageUserWrapper.buildEntity(h.doc(0)); + assertTrue(storedUser.equals(user)); + + assertFalse(storedUser.getPassword().equals(password)); + searcher.close(); + } + + public void testSaveFeed() throws IOException, StorageException { + Feed feed = new Feed(); + String title = "myTitle"; + + feed.setTitle(new PlainTextConstruct(title)); + feed.setId(feedId); + StorageFeedWrapper wrapper = new StorageFeedWrapper(feed,username,this.configurator); + this.modifier.createFeed(wrapper); + IndexSearcher searcher = new IndexSearcher(this.dir); + Query q = new TermQuery(new Term(StorageFeedWrapper.FIELD_FEED_ID, + feedId)); + Hits h = searcher.search(q); + assertEquals("length == 1", 1, h.length()); + searcher.close(); + } + + public void testDeleteFeed() throws IOException, StorageException { + testSaveFeed(); + this.modifier.deleteFeed(feedId); + IndexSearcher searcher = new IndexSearcher(this.dir); + Query q = new TermQuery(new Term(StorageFeedWrapper.FIELD_FEED_ID, + feedId)); + Hits h = searcher.search(q); + assertEquals("length == 0", 0, h.length()); + searcher.close(); - } - - protected void tearDown() throws Exception { - this.count = 1; - // destroy all resources - GDataServerRegistry.getRegistry().destroy();//TODO remove dependency here - - } - - /* - * Test method for - * 'org.apache.lucene.storage.lucenestorage.StorageModifier.StorageModifier(Directory, - * int)' - */ - public void testStorageModifier() { - - } - - /* - * Test method for - * 'org.apache.lucene.storage.lucenestorage.StorageModifier.updateEntry(StroageEntryWrapper)' - */ - public void testUpdateEntry() throws IOException, InterruptedException, FeedNotFoundException, ParseException, StorageException { - testInsertEntry(); - for(int i = 1; i < this.count; i++){ - Entry e = new Entry(); - e.setId(""+i); - String insertString = "Hello world"+i; - e.setTitle(new PlainTextConstruct(insertString)); - StorageEntryWrapper wrapper = new StorageEntryWrapper(e,feedId,StorageOperation.UPDATE,this.profile); - this.modifier.updateEntry(wrapper); - ReferenceCounter innerQuery = StorageCoreController.getStorageCoreController().getStorageQuery(); - BaseEntry fetchedEntry = innerQuery.get().singleEntryQuery(""+i,feedId,this.profile); - assertEquals("updated Title:",insertString,fetchedEntry.getTitle().getPlainText()); - } - // double updates - for(int i = 1; i < this.count; i++){ - Entry e = new Entry(); - e.setId(""+i); - String insertString = "Hello world"+i; - e.setTitle(new PlainTextConstruct(insertString)); - StorageEntryWrapper wrapper = new StorageEntryWrapper(e,feedId,StorageOperation.UPDATE,this.profile); - this.modifier.updateEntry(wrapper); - - e = new Entry(); - e.setId(""+i); - insertString = "Foo Bar"+i; - e.setTitle(new PlainTextConstruct(insertString)); - wrapper = new StorageEntryWrapper(e,feedId,StorageOperation.UPDATE,this.profile); - this.modifier.updateEntry(wrapper); - - ReferenceCounter innerQuery = StorageCoreController.getStorageCoreController().getStorageQuery(); - - BaseEntry fetchedEntry = innerQuery.get().singleEntryQuery(""+i,feedId,this.profile); - assertEquals("updated Title:",insertString,fetchedEntry.getTitle().getPlainText()); - } - - - - } - - /* - * Test method for - * 'org.apache.lucene.storage.lucenestorage.StorageModifier.insertEntry(StroageEntryWrapper)' - */ - public void testInsertEntry() throws IOException, InterruptedException, FeedNotFoundException, ParseException, StorageException { - Thread a = getRunnerThread(this.count); - a.start(); - - Thread b = getRunnerThread((this.count+=10)); - b.start(); - a.join(); - for (int i = 1; i < this.count ; i++) { - ReferenceCounter innerQuery = StorageCoreController.getStorageCoreController().getStorageQuery(); - BaseEntry e = innerQuery.get().singleEntryQuery(""+i,feedId,this.profile); - assertEquals("get entry for id"+i,""+i,e.getId()); - - - } - b.join(); - ReferenceCounter query = StorageCoreController.getStorageCoreController().getStorageQuery(); - - this.count+=10; - for (int i = 1; i < this.count ; i++) { - BaseEntry e = query.get().singleEntryQuery(""+i,feedId,this.profile); - assertEquals("get entry for id"+i,""+i,e.getId()); - } - BaseEntry e = query.get().singleEntryQuery(""+this.count,feedId,this.profile); - assertNull("not entry for ID",e); - query.decrementRef(); - - } - - /* - * Test method for - * 'org.apache.lucene.storage.lucenestorage.StorageModifier.deleteEntry(String)' - */ - public void testDeleteEntry() throws IOException, InterruptedException, FeedNotFoundException, ParseException, StorageException { - testInsertEntry(); - for (int i = 1; i < this.count ; i++) { - if(i%2 == 0 || i< 10){ - this.modifier.deleteEntry(""+i,feedId); - } - ReferenceCounter query = StorageCoreController.getStorageCoreController().getStorageQuery(); - if(i%2 == 0 || i< 10){ - assertNull(query.get().singleEntryQuery(""+i,feedId,this.profile)); - } - else - assertEquals(""+i,query.get().singleEntryQuery(""+i,feedId,this.profile).getId()); - query.decrementRef(); - } - - StorageCoreController.getStorageCoreController().forceWrite(); - IndexSearcher searcher = new IndexSearcher(this.dir); - - for (int i = 1; i < this.count ; i++) { - Query luceneQuery = new TermQuery(new Term(StorageEntryWrapper.FIELD_ENTRY_ID,""+i)); - Hits hits = searcher.search(luceneQuery); - if(i%2 == 0 || i< 10){ - - assertEquals(0,hits.length()); - } - else - assertEquals(1,hits.length()); - } - searcher.close(); - - } - - - private Thread getRunnerThread(int idIndex){ - Thread t = new Thread(new Runner(idIndex)); - return t; - } - - private class Runner implements Runnable{ - private int idIndex; - public Runner(int idIndex){ - this.idIndex = idIndex; - } - public void run() { - for (int i = idIndex; i < idIndex+10; i++) { - - BaseEntry e = buildEntry(""+i); - try { - StorageEntryWrapper wrapper = new StorageEntryWrapper(e,feedId,StorageOperation.INSERT,new ExtensionProfile()); - modifier.insertEntry(wrapper); - } catch (Exception e1) { - - e1.printStackTrace(); - } - - - - - } - - - }//end run - - private BaseEntry buildEntry(String id){ - Entry e = new Entry(); - e.setId(id); - e.setTitle(new PlainTextConstruct("Monty Python")); - - e.setPublished(DateTime.now()); - - e.setUpdated(DateTime.now()); - String content = "1st soldier with a keen interest in birds: Who goes there?" + - "King Arthur: It is I, Arthur, son of Uther Pendragon, from the castle of Camelot. King of the Britons, defeater of the Saxons, Sovereign of all England!" + - "1st soldier with a keen interest in birds: Pull the other one!" + - "King Arthur: I am, and this is my trusty servant Patsy. We have ridden the length and breadth of the land in search of knights who will join me in my court at Camelot. I must speak with your lord and master." + - "1st soldier with a keen interest in birds: What? Ridden on a horse?" + - "King Arthur: Yes!"; - e.setContent(new TextContent(new PlainTextConstruct(content))); - e.setSummary(new PlainTextConstruct("The Holy Grail")); - return e; - } - - } - -} + } + + /** + * @throws IOException + * @throws StorageException + */ + public void testUpdateFeed() throws IOException, StorageException { + testSaveFeed(); + Feed feed = new Feed(); + String title = "myTitle"; + String newusername = "doug"; + feed.setTitle(new PlainTextConstruct(title)); + feed.setId(feedId); + StorageFeedWrapper wrapper = new StorageFeedWrapper(feed,newusername,this.configurator); + this.modifier.updateFeed(wrapper); + IndexSearcher searcher = new IndexSearcher(this.dir); + Query q = new TermQuery(new Term(StorageFeedWrapper.FIELD_FEED_ID, + feedId)); + Hits h = searcher.search(q); + assertEquals("length == 1", 1, h.length()); + assertTrue(h.doc(0).get(StorageFeedWrapper.FIELD_USERNAME).equals(newusername)); + searcher.close(); + + } + + private Thread getRunnerThread(int idIndex) { + Thread t = new Thread(new Runner(idIndex)); + return t; + } + + private class Runner implements Runnable { + private int idIndex; + + public Runner(int idIndex) { + this.idIndex = idIndex; + } + + public void run() { + for (int i = idIndex; i < idIndex + 10; i++) { + + BaseEntry e = buildEntry("" + i); + try { + StorageEntryWrapper wrapper = new StorageEntryWrapper(e, + feedId, StorageOperation.INSERT, configurator); + modifier.insertEntry(wrapper); + } catch (Exception e1) { + + e1.printStackTrace(); + } + + } + + }// end run + + private BaseEntry buildEntry(String id) { + Entry e = new Entry(); + e.setId(id); + e.setTitle(new PlainTextConstruct("Monty Python")); + + e.setPublished(DateTime.now()); + + e.setUpdated(DateTime.now()); + String content = "1st soldier with a keen interest in birds: Who goes there?" + + "King Arthur: It is I, Arthur, son of Uther Pendragon, from the castle of Camelot. King of the Britons, defeater of the Saxons, Sovereign of all England!" + + "1st soldier with a keen interest in birds: Pull the other one!" + + "King Arthur: I am, and this is my trusty servant Patsy. We have ridden the length and breadth of the land in search of knights who will join me in my court at Camelot. I must speak with your lord and master." + + "1st soldier with a keen interest in birds: What? Ridden on a horse?" + + "King Arthur: Yes!"; + e.setContent(new TextContent(new PlainTextConstruct(content))); + e.setSummary(new PlainTextConstruct("The Holy Grail")); + return e; + } + + } + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageQuery.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageQuery.java (revision 413530) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageQuery.java (working copy) @@ -1,175 +1,203 @@ -package org.apache.lucene.gdata.storage.lucenestorage; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import junit.framework.TestCase; - -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.gdata.server.FeedNotFoundException; -import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; -import org.apache.lucene.gdata.server.registry.GDataServerRegistry; -import org.apache.lucene.gdata.server.registry.RegistryBuilder; -import org.apache.lucene.gdata.storage.StorageException; -import org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController; -import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper; -import org.apache.lucene.gdata.storage.lucenestorage.StorageModifier; -import org.apache.lucene.gdata.storage.lucenestorage.StorageQuery; -import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation; -import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.RAMDirectory; - -import com.google.gdata.data.BaseEntry; -import com.google.gdata.data.DateTime; -import com.google.gdata.data.Entry; -import com.google.gdata.data.ExtensionProfile; -import com.google.gdata.data.Feed; -import com.google.gdata.util.ParseException; - -public class TestStorageQuery extends TestCase { - private StorageModifier modifier; - private int count = 30; - private ReferenceCounter query; - private ExtensionProfile profile; - - private Directory dir; - private static String feedId = "myFeed"; - protected void setUp() throws Exception { - FeedInstanceConfigurator configurator = new FeedInstanceConfigurator(); - configurator.setFeedType(Feed.class); - configurator.setFeedId(feedId); - configurator.setExtensionProfileClass(ExtensionProfile.class); - GDataServerRegistry.getRegistry().registerFeed(configurator); - this.profile = new ExtensionProfile(); - this.dir = new RAMDirectory(); - IndexWriter writer; - writer = new IndexWriter(this.dir,new StandardAnalyzer(),true); - writer.close(); - this.modifier = StorageCoreController.getStorageCoreController(this.dir).getStorageModifier(); - insertEntries(this.count); - this.query = StorageCoreController.getStorageCoreController().getStorageQuery(); +package org.apache.lucene.gdata.storage.lucenestorage; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.lucene.gdata.data.GDataUser; +import org.apache.lucene.gdata.server.registry.ComponentType; +import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; +import org.apache.lucene.gdata.server.registry.GDataServerRegistry; +import org.apache.lucene.gdata.storage.StorageController; +import org.apache.lucene.gdata.storage.StorageException; +import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation; +import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter; +import org.apache.lucene.store.Directory; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.DateTime; +import com.google.gdata.data.Entry; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.data.Feed; +import com.google.gdata.util.ParseException; + +public class TestStorageQuery extends TestCase { + private StorageModifier modifier; + private int count = 30; + private ReferenceCounter query; + private FeedInstanceConfigurator configurator; + private StorageCoreController controller; + private Directory dir; + private static String feedId = "myFeed"; + protected void setUp() throws Exception { + GDataServerRegistry.getRegistry().registerComponent(StorageCoreController.class); + this.configurator = new FeedInstanceConfigurator(); + this.configurator.setFeedType(Feed.class); + this.configurator.setExtensionProfile(new ExtensionProfile()); + GDataServerRegistry.getRegistry().registerFeed(this.configurator); + this.controller = (StorageCoreController)GDataServerRegistry.getRegistry().lookup(StorageController.class,ComponentType.STORAGECONTROLLER); + this.modifier = this.controller.getStorageModifier(); + this.dir = this.controller.getDirectory(); + Feed feed = new Feed(); + feed.setId(feedId); + StorageFeedWrapper wrapper = new StorageFeedWrapper(feed,"simon",this.configurator); + this.modifier.createFeed(wrapper); + insertEntries(this.count); + this.query = this.controller.getStorageQuery(); + - - - } - - - public void insertEntries(int count) throws IOException,InterruptedException, StorageException{ - List tempList = new ArrayList(); - for (int i = 0; i <= count ; i++) { - Entry entry = new Entry(); - entry.setId(""+i); - - entry.setUpdated(new DateTime(System.currentTimeMillis(),0)); - StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,feedId,StorageOperation.INSERT,this.profile); - tempList.add(i,wrapper); + + + } + + + /** + * @param entrycount + * @throws IOException + * @throws InterruptedException + * @throws StorageException + */ + public void insertEntries(int entrycount) throws IOException,InterruptedException, StorageException{ + List tempList = new ArrayList(); + for (int i = 0; i <= entrycount ; i++) { + Entry entry = new Entry(); + entry.setId(""+i); - // force different timestamps --> DateTime 2006-06-05T13:37:55.724Z - Thread.sleep(50); + entry.setUpdated(new DateTime(System.currentTimeMillis(),0)); + StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,feedId,StorageOperation.INSERT,this.configurator); + tempList.add(i,wrapper); - } - for (StorageEntryWrapper entry : tempList) { - this.modifier.insertEntry(entry); - } - - - - - } - - protected void tearDown() throws Exception { - this.query.decrementRef(); - GDataServerRegistry.getRegistry().destroy();//TODO remove dependency here - } - - /* - * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.feedQuery(String, int, int)' - */ - public void testFeedQuery() throws IOException, FeedNotFoundException, ParseException, StorageException { - FeedQueryHelper(this.query); - StorageCoreController.getStorageCoreController().forceWrite(); - ReferenceCounter queryAssureWritten = StorageCoreController.getStorageCoreController().getStorageQuery(); + // force different timestamps --> DateTime 2006-06-05T13:37:55.724Z + Thread.sleep(50); + + } + for (StorageEntryWrapper entry : tempList) { + this.modifier.insertEntry(entry); + } - assertNotSame(queryAssureWritten,this.query); - FeedQueryHelper(queryAssureWritten); - queryAssureWritten.decrementRef(); - } - private void FeedQueryHelper(ReferenceCounter currentQuery) throws IOException, FeedNotFoundException, ParseException{ - List entryList = currentQuery.get().getLatestFeedQuery(feedId,25,1,this.profile); - - assertTrue("listSize: "+entryList.size(),entryList.size() == 25); - - BaseEntry tempEntry = null; - for (BaseEntry entry : entryList) { - - assertNotNull("entry",entry); - if(tempEntry != null){ - assertTrue(tempEntry.getUpdated().compareTo(entry.getUpdated())>=0) ; - tempEntry = entry; - }else - tempEntry = entry; - - } - // test sub retrieve sublist - int offset = 15; - int resultCount = 5; - List entrySubList = currentQuery.get().getLatestFeedQuery(feedId,resultCount,offset,this.profile); - - assertTrue("listSize: "+entrySubList.size(),entrySubList.size() == resultCount); - offset--; - for (BaseEntry entry : entrySubList) { - - assertEquals(entry.getId(),entryList.get(offset).getId()); - offset++; - - } - - - - } - - /* - * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.singleEntryQuery(String, String)' - */ - public void testSingleEntryQuery() throws FeedNotFoundException, ParseException, IOException { - for (int i = 1; i <= this.count; i++) { - BaseEntry entry = this.query.get().singleEntryQuery(""+i,feedId,this.profile); - assertEquals(""+i,entry.getId()); - } - - } - - /* - * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.entryQuery(List, String)' - */ - public void testEntryQuery() throws FeedNotFoundException, ParseException, IOException, StorageException { - entryQueryHelper(this.query); - StorageCoreController.getStorageCoreController().forceWrite(); - ReferenceCounter queryAssureWritten = StorageCoreController.getStorageCoreController().getStorageQuery(); - assertNotSame(queryAssureWritten,query); - entryQueryHelper(queryAssureWritten); - queryAssureWritten.decrementRef(); - } + + + } + + protected void tearDown() throws Exception { + this.query.decrementRef(); + GDataServerRegistry.getRegistry().destroy();//TODO remove dependency here + } + + /* + * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.feedQuery(String, int, int)' + */ + public void testFeedQuery() throws IOException, ParseException, StorageException { + feedQueryHelper(this.query); + this.controller.forceWrite(); + ReferenceCounter queryAssureWritten = this.controller.getStorageQuery(); + + assertNotSame(queryAssureWritten,this.query); + feedQueryHelper(queryAssureWritten); + queryAssureWritten.decrementRef(); + } + private void feedQueryHelper(ReferenceCounter currentQuery) throws IOException, ParseException{ + BaseFeed feed = currentQuery.get().getLatestFeedQuery(feedId,25,1,this.configurator); + List entryList = feed.getEntries(); + assertTrue("listSize: "+entryList.size(),entryList.size() == 25); + + BaseEntry tempEntry = null; + for (BaseEntry entry : entryList) { + + assertNotNull("entry",entry); + if(tempEntry != null){ + assertTrue(tempEntry.getUpdated().compareTo(entry.getUpdated())>=0) ; + tempEntry = entry; + }else + tempEntry = entry; + + } + // test sub retrieve sublist + int offset = 15; + int resultCount = 5; + feed = currentQuery.get().getLatestFeedQuery(feedId,resultCount,offset,this.configurator); + List entrySubList = feed.getEntries(); + + assertTrue("listSize: "+entrySubList.size(),entrySubList.size() == resultCount); + offset--; + for (BaseEntry entry : entrySubList) { + + assertEquals(entry.getId(),entryList.get(offset).getId()); + offset++; + + } + + + + } + + /* + * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.singleEntryQuery(String, String)' + */ + public void testSingleEntryQuery() throws ParseException, IOException { + for (int i = 1; i <= this.count; i++) { + BaseEntry entry = this.query.get().singleEntryQuery(""+i,feedId,this.configurator); + assertEquals(""+i,entry.getId()); + } + + } + + /* + * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.entryQuery(List, String)' + */ + public void testEntryQuery() throws ParseException, IOException, StorageException { + entryQueryHelper(this.query); + this.controller.forceWrite(); + ReferenceCounter queryAssureWritten = this.controller.getStorageQuery(); + + assertNotSame(queryAssureWritten,query); + entryQueryHelper(queryAssureWritten); + queryAssureWritten.decrementRef(); + } + public void testGetUser() throws StorageException, IOException{ + this.modifier.forceWrite(); + GDataUser user = new GDataUser("simon"); + user.setPassword("pass"); + user.setAuthorname("simon willnauer"); + user.setAuthorMail("simon@apache.org"); + user.setAuthorLink(new URL("http://www.apache.org")); + + - - private void entryQueryHelper(ReferenceCounter currentQuery) throws IOException, FeedNotFoundException, ParseException{ - - List entryIdList = new ArrayList(); - for (int i = 1; i <= this.count; i++) { - entryIdList.add(""+i); - } - List entryList = currentQuery.get().entryQuery(entryIdList,feedId,this.profile); - assertEquals(entryIdList.size(),entryList.size()); - List entryIdCompare = new ArrayList(); - for (BaseEntry entry : entryList) { - entryIdCompare.add(entry.getId()); - } - assertTrue(entryIdList.containsAll(entryIdCompare)); - - } - -} + this.modifier.createUser(new StorageUserWrapper(user)); + GDataUser queriedUser = this.query.get().getUser("simon"); + assertNull(queriedUser); + ReferenceCounter tempQuery = this.controller.getStorageQuery(); + queriedUser = tempQuery.get().getUser("simon"); + assertTrue(queriedUser.equals(user)); + assertTrue(queriedUser.getAuthorMail().equals(user.getAuthorMail())); + assertTrue(queriedUser.getAuthorLink().equals(user.getAuthorLink())); + assertTrue(queriedUser.getAuthorname().equals(user.getAuthorname())); + assertTrue(queriedUser.getPassword().equals(user.getPassword())); + } + + + private void entryQueryHelper(ReferenceCounter currentQuery) throws IOException, ParseException{ + + List entryIdList = new ArrayList(); + for (int i = 1; i <= this.count; i++) { + entryIdList.add(""+i); + } + List entryList = currentQuery.get().entryQuery(entryIdList,feedId,this.configurator); + assertEquals(entryIdList.size(),entryList.size()); + List entryIdCompare = new ArrayList(); + for (BaseEntry entry : entryList) { + entryIdCompare.add(entry.getId()); + } + assertTrue(entryIdList.containsAll(entryIdCompare)); + + } + + + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java (revision 413530) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java (working copy) @@ -15,23 +15,22 @@ */ package org.apache.lucene.gdata.server.registry; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; + +import junit.framework.TestCase; + +import org.apache.lucene.gdata.server.GDataEntityBuilder; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.Entry; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.data.Feed; +import com.google.gdata.util.ParseException; -import junit.framework.TestCase; - -import org.apache.lucene.gdata.server.FeedNotFoundException; -import org.apache.lucene.gdata.server.GDataEntityBuilder; - -import com.google.gdata.data.BaseEntry; -import com.google.gdata.data.BaseFeed; -import com.google.gdata.data.Entry; -import com.google.gdata.data.ExtensionProfile; -import com.google.gdata.data.Feed; -import com.google.gdata.util.ParseException; - /** * @author Simon Willnauer * @@ -44,7 +43,7 @@ private static GDataServerRegistry reg = GDataServerRegistry.getRegistry(); private Reader reader; private static String feedID = "myFeed"; - private ExtensionProfile profile; + private FeedInstanceConfigurator config; private static Class feedType = Feed.class; @@ -53,11 +52,11 @@ */ @Override protected void setUp() throws Exception { - FeedInstanceConfigurator config = new FeedInstanceConfigurator(); - config.setFeedId(feedID); - config.setFeedType(feedType); - this.profile = new ExtensionProfile(); - reg.registerFeed(config); + this.config = new FeedInstanceConfigurator(); + + this.config.setFeedType(feedType); + this.config.setExtensionProfile(new ExtensionProfile()); + reg.registerFeed(this.config); } /** @@ -72,21 +71,21 @@ /** * Test method for 'org.apache.lucene.gdata.data.GDataEntityBuilder.buildFeed(String, Reader)' */ - public void testBuildFeedStringReader() throws FeedNotFoundException, ParseException, IOException { + public void testBuildFeedStringReader() throws ParseException, IOException { this.reader = new FileReader(incomingFeed); - BaseFeed feed = GDataEntityBuilder.buildFeed(feedID,this.reader,this.profile); + BaseFeed feed = GDataEntityBuilder.buildFeed(feedID,this.reader,this.config); assertNotNull(feed); assertEquals("feed title",feed.getTitle().getPlainText(), feedTitleFromXML); assertTrue( feed instanceof Feed); } - /* + /** * Test method for 'org.apache.lucene.gdata.data.GDataEntityBuilder.buildEntry(String, Reader)' */ - public void testBuildEntryStringReader() throws FeedNotFoundException, ParseException, IOException { + public void testBuildEntryStringReader() throws ParseException, IOException { this.reader = new FileReader(incomingEntry); - BaseEntry entry = GDataEntityBuilder.buildEntry(feedID,this.reader,this.profile); + BaseEntry entry = GDataEntityBuilder.buildEntry(feedID,this.reader,this.config); assertNotNull(entry); assertEquals("entry summary",entry.getSummary().getPlainText(),entrySummaryFromXML); assertTrue(entry instanceof Entry); Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java (revision 413530) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java (working copy) @@ -1,98 +1,126 @@ -/** - * Copyright 2004 The Apache Software Foundation - * - * 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.apache.lucene.gdata.server.registry; - -import com.google.gdata.data.Feed; - -import junit.framework.TestCase; - -/** - * @author Simon Willnauer - * - */ -public class TestFeedRegistry extends TestCase { - private GDataServerRegistry reg; - private FeedInstanceConfigurator configurator; - @Override - protected void setUp(){ - this.reg = GDataServerRegistry.getRegistry(); - this.configurator = new FeedInstanceConfigurator(); - } - /** - * @see junit.framework.TestCase#tearDown() - */ - @Override - protected void tearDown() throws Exception { - this.reg.flushRegistry(); - } - /** - * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getRegistry()' - */ - public void testGetRegistry() { - - GDataServerRegistry reg1 = GDataServerRegistry.getRegistry(); - assertEquals("test singleton",this.reg,reg1); - } - - /** - * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.registerFeed(FeedInstanceConfigurator)' - */ - public void testRegisterFeed() { - String feedURL = "myFeed"; - registerFeed(feedURL); - assertEquals("Registered Configurator",this.configurator,this.reg.getFeedConfigurator(feedURL)); - assertNull("not registered Configurator",this.reg.getFeedConfigurator("somethingElse")); - try{ - this.reg.getFeedConfigurator(null); - fail("Exception expected"); - }catch (IllegalArgumentException e) { - // - } - } - - /** - * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getFeedConfigurator(String)' - */ - public void testFlushRegistry() { - String feedURL = "testFeed"; - registerFeed(feedURL); - assertEquals("Registered Configurator",this.configurator,this.reg.getFeedConfigurator(feedURL)); - this.reg.flushRegistry(); - assertNull("Registry flushed",this.reg.getFeedConfigurator(feedURL)); - - - } - - /** - * - */ - public void testIsFeedRegistered(){ - String myFeed = "myFeed"; - registerFeed(myFeed); - assertTrue("Feed is registerd",this.reg.isFeedRegistered(myFeed)); - assertFalse("null Feed is not registerd",this.reg.isFeedRegistered(null)); - assertFalse("Feed is not registerd",this.reg.isFeedRegistered("someOtherFeed")); - - } - - private void registerFeed(String feedURL){ - - this.configurator.setFeedType(Feed.class); - this.configurator.setFeedId(feedURL); - this.reg.registerFeed(this.configurator); - } - -} +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.server.registry; + +import org.apache.lucene.gdata.server.ServiceFactory; +import org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory; +import org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory; +import org.apache.lucene.gdata.storage.StorageController; +import org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController; + +import com.google.gdata.data.Feed; + +import junit.framework.TestCase; + +/** + * @author Simon Willnauer + * + */ +public class TestFeedRegistry extends TestCase { + private GDataServerRegistry reg; + private FeedInstanceConfigurator configurator; + @Override + protected void setUp(){ + this.reg = GDataServerRegistry.getRegistry(); + this.configurator = new FeedInstanceConfigurator(); + } + /** + * @see junit.framework.TestCase#tearDown() + */ + @Override + protected void tearDown() throws Exception { + this.reg.flushRegistry(); + } + /** + * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getRegistry()' + */ + public void testGetRegistry() { + + GDataServerRegistry reg1 = GDataServerRegistry.getRegistry(); + assertEquals("test singleton",this.reg,reg1); + } + + /** + * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.registerFeed(FeedInstanceConfigurator)' + */ + public void testRegisterFeed() { + Class feedType = Feed.class; + registerFeed(feedType); + assertEquals("Registered Configurator",this.configurator,this.reg.getFeedConfigurator(feedType.getName())); + assertNull("not registered Configurator",this.reg.getFeedConfigurator(String.class.getName())); + try{ + this.reg.getFeedConfigurator(null); + fail("Exception expected"); + }catch (IllegalArgumentException e) { + // + } + } + + /** + * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getFeedConfigurator(String)' + */ + public void testFlushRegistry() { + Class feedType = Feed.class; + registerFeed(feedType); + assertEquals("Registered Configurator",this.configurator,this.reg.getFeedConfigurator(feedType.getName())); + this.reg.flushRegistry(); + assertNull("Registry flushed",this.reg.getFeedConfigurator(feedType.getName())); + + + } + + /** + * + */ + public void testIsFeedRegistered(){ + Class myFeed = Feed.class; + registerFeed(myFeed); + assertTrue("Feed is registerd",this.reg.isFeedRegistered(Feed.class.getName())); + assertFalse("null Feed is not registerd",this.reg.isFeedRegistered(null)); + assertFalse("Feed is not registerd",this.reg.isFeedRegistered(String.class.getName())); + + } + + private void registerFeed(Class clazz){ + + this.configurator.setFeedType(clazz); + this.reg.registerFeed(this.configurator); + } + + public void testRegisterComponent() throws RegistryException{ + try { + this.reg.registerComponent(StorageController.class); + fail("RegistryException expected"); + } catch (RegistryException e) { + // + } + this.reg.registerComponent(DefaultRequestHandlerFactory.class); + RequestHandlerFactory factory = this.reg.lookup(RequestHandlerFactory.class,ComponentType.REQUESTHANDLERFACTORY); + try{ + this.reg.registerComponent(DefaultRequestHandlerFactory.class); + fail("RegistryException expected"); + } catch (RegistryException e) { + // + } + this.reg.registerComponent(ServiceFactory.class); + ServiceFactory servicefactory = this.reg.lookup(ServiceFactory.class,ComponentType.SERVICEFACTORY); + assertNotNull(servicefactory); + assertNotNull(factory); + + + } + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java (revision 413530) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java (working copy) @@ -15,6 +15,8 @@ */ package org.apache.lucene.gdata.server; +import java.util.Enumeration; + import javax.servlet.http.HttpServletRequest; import junit.framework.TestCase; @@ -44,8 +46,8 @@ protected void setUp() throws Exception { FeedInstanceConfigurator configurator = new FeedInstanceConfigurator(); configurator.setFeedType(Feed.class); - configurator.setFeedId("feed"); - configurator.setExtensionProfileClass(ExtensionProfile.class); + + configurator.setExtensionProfile(new ExtensionProfile()); GDataServerRegistry.getRegistry().registerFeed(configurator); this.control = MockControl.createControl(HttpServletRequest.class); this.request = (HttpServletRequest) this.control.getMock(); @@ -347,36 +349,42 @@ } public void testGetNextId() throws GDataRequestException{ -// String host = "www.apache.org"; -// String feedAndEntryID = "/feed/entryid"; -// String queryString = "?max-results=25"; -// String startIndex = "&start-index=26"; -// this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host); -// this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/entryId/15"); -// this.control.expectAndReturn(this.request.getParameter("max-results"),"25",2); -// this.control.expectAndReturn(this.request.getParameter("start-index"),null); -// this.control.expectAndDefaultReturn(this.request.getParameter("alt"), -// null); -// this.control.expectAndDefaultReturn(this.request.getQueryString(), -// queryString); -// this.control.replay(); -// this.feedRequest.initializeRequest(); -// String nextID = "http://"+host+"/feed"+queryString+startIndex; -// -// assertEquals("Next ID",nextID,this.feedRequest.getNextId()); -// this.control.reset(); -// -// + String host = "www.apache.org"; + String feedAndEntryID = "/feed/entryid"; + String queryString = "?max-results=25"; + String startIndex = "&start-index=26"; + this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host); + this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/feed/"); + this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/"); + this.control.expectAndReturn(this.request.getParameter("max-results"),"25",2); + this.control.expectAndReturn(this.request.getParameter("start-index"),null); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + null); + this.control.expectAndDefaultReturn(this.request.getQueryString(), + queryString); + this.control.replay(); + this.feedRequest.initializeRequest(); + String nextID = "http://"+host+"/feed/"+queryString+startIndex; + + assertEquals("Next ID",nextID,this.feedRequest.getNextId()); + this.control.reset(); + + // queryString = "?alt=rss&max-results=25"; // // this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host); -// this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/entryId/15"); +// this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/feed/"); +// this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/"); // this.control.expectAndReturn(this.request.getParameter("max-results"),"25",2); // this.control.expectAndReturn(this.request.getParameter("start-index"),"26",2); // this.control.expectAndDefaultReturn(this.request.getParameter("alt"), // null); // this.control.expectAndDefaultReturn(this.request.getQueryString(), // queryString+startIndex); +// Enumeration e = +// this.control.expectAndDefaultReturn(this.request.getParameterNames(),) +// +// // this.control.replay(); // this.feedRequest.initializeRequest(); // startIndex = "&start-index=51"; @@ -395,7 +403,7 @@ // null); // this.control.replay(); // this.feedRequest.initializeRequest(); -// selfID = "http://"+host+"/feed"+"?max-results=25"; +// String selfID = "http://"+host+"/feed"+"?max-results=25"; // // assertEquals("Self ID",selfID,this.feedRequest.getSelfId()); // this.control.reset(); Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/data/TestGDataUser.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/data/TestGDataUser.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/data/TestGDataUser.java (revision 0) @@ -0,0 +1,60 @@ +package org.apache.lucene.gdata.data; + +import org.apache.lucene.gdata.data.GDataUser.UserRole; + +import junit.framework.TestCase; + +public class TestGDataUser extends TestCase { + private GDataUser user; + @Override + protected void setUp() throws Exception { + this.user = new GDataUser("Simon"); + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + + super.tearDown(); + } + + /* + * Test method for 'org.apache.lucene.gdata.data.GDataUser.isUserInRole(UserRole)' + */ + public void testIsUserInRole() { + assertTrue(this.user.isUserInRole(UserRole.USER)); + assertFalse(this.user.isUserInRole(UserRole.ENTRYAMINISTRATOR)); + this.user.setRole(UserRole.ENTRYAMINISTRATOR); + assertTrue(this.user.isUserInRole(UserRole.ENTRYAMINISTRATOR)); + } + + /* + * Test method for 'org.apache.lucene.gdata.data.GDataUser.getRolesAsInt()' + */ + public void testGetRolesAsInt() { + assertEquals(1,this.user.getRolesAsInt()); + this.user.setRole(UserRole.ENTRYAMINISTRATOR); + assertEquals(3,this.user.getRolesAsInt()); + this.user.setRole(UserRole.FEEDAMINISTRATOR); + assertEquals(7,this.user.getRolesAsInt()); + this.user.setRole(UserRole.USERADMINISTRATOR); + assertEquals(15,this.user.getRolesAsInt()); + + } + + /* + * Test method for 'org.apache.lucene.gdata.data.GDataUser.setRolesAsInt(int)' + */ + public void testSetRolesAsInt() { + this.user.setRolesAsInt(2); + this.user.setRolesAsInt(4); + this.user.setRolesAsInt(8); + assertEquals(4,this.user.getRoles().size()); + this.user.setRolesAsInt(15); + assertEquals(4,this.user.getRoles().size()); + this.user = new GDataUser("simon"); + this.user.setRolesAsInt(15); + assertEquals(4,this.user.getRoles().size()); + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java (working copy) @@ -1,122 +1,103 @@ -/** - * Copyright 2004 The Apache Software Foundation +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.servlet; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.servlet.handler.GDataRequestHandler; + +/** + * Provides a clean basic interface for GDATA Client API and requests to the + * GDATA Server. This Servlet dispatches the incoming requests to defined GDATA + * request handlers. Each of the handler processes the incoming request and + * responds according to the requested action. * - * 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 + * @author Simon Willnauer * - * 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.lucene.gdata.servlet; - -import java.io.IOException; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory; -import org.apache.lucene.gdata.servlet.handler.GDataRequestHandler; -import org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory; - -/** - * Provides a clean basic interface for GDATA Client API and requests to the - * GDATA Server. This Servlet dispatches the incoming requests to defined GDATA - * request handlers. Each of the handler processes the incoming request and - * responds according to the requested action. - * - * @author Simon Willnauer - * - */ -public class RequestControllerServlet extends AbstractGdataServlet { - private static RequestHandlerFactory HANDLER_FACTORY = null; - private static final Log LOGGER = LogFactory.getLog(RequestControllerServlet.class); - - /** - * Version ID since this class implements - * - * @see java.io.Serializable - */ - private static final long serialVersionUID = 7540810742476175576L; - - /** - * @see javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - @Override - protected void doDelete(HttpServletRequest arg0, HttpServletResponse arg1) - throws ServletException, IOException { - GDataRequestHandler hanlder = HANDLER_FACTORY.getDeleteHandler(); - if(LOGGER.isInfoEnabled()) - LOGGER.info("Process DELETE request"); - - hanlder.processRequest(arg0, arg1); - } - - /** - * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - @Override - protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) - throws ServletException, IOException { - GDataRequestHandler hanlder = HANDLER_FACTORY.getQueryHandler(); - if(LOGGER.isInfoEnabled()) - LOGGER.info("Process GET request"); - - hanlder.processRequest(arg0, arg1); - } - - /** - * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - @Override - protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) - throws ServletException, IOException { - GDataRequestHandler hanlder = HANDLER_FACTORY.getInsertHandler(); - if(LOGGER.isInfoEnabled()) - LOGGER.info("Process POST request"); - hanlder.processRequest(arg0, arg1); - } - - /** - * @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - @Override - protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) - throws ServletException, IOException { - GDataRequestHandler hanlder = HANDLER_FACTORY.getUpdateHandler(); - if(LOGGER.isInfoEnabled()) - LOGGER.info("Process PUT request"); - hanlder.processRequest(arg0, arg1); - } - - /** - * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) - */ - @Override - public void init(ServletConfig arg0) { - /* - * The Factory implementation could be configured as an initial - * parameter or by an external config file. - * - */ - HANDLER_FACTORY = RequestHandlerFactory - .getInstance(DefaultRequestHandlerFactory.class); - - } - - -} + */ +public class RequestControllerServlet extends AbstractGdataServlet { + private static final Log LOGGER = LogFactory.getLog(RequestControllerServlet.class); + + /** + * Version ID since this class implements + * + * @see java.io.Serializable + */ + private static final long serialVersionUID = 7540810742476175576L; + + /** + * @see javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doDelete(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getEntryDeleteHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process DELETE request"); + + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getFeedQueryHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process GET request"); + + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getEntryInsertHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process POST request"); + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getEntryUpdateHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process PUT request"); + hanlder.processRequest(arg0, arg1); + } + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AccountAdministrationServlet.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AccountAdministrationServlet.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AccountAdministrationServlet.java (revision 0) @@ -0,0 +1,73 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.servlet; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.servlet.handler.GDataRequestHandler; + +/** + * This Servlet provides an REST interface to create / update and delete user instances. + * @author Simon Willnauer + * + */ +public class AccountAdministrationServlet extends AbstractGdataServlet { + + private static final Log LOGGER = LogFactory.getLog(AccountAdministrationServlet.class); + + /** + * + */ + private static final long serialVersionUID = 8215863212137543185L; + + @Override + protected void doDelete(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { + GDataRequestHandler handler = HANDLER_FACTORY.getDeleteUserHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process delete User request"); + handler.processRequest(arg0,arg1); + + } + + @Override + protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { + GDataRequestHandler handler = HANDLER_FACTORY.getInsertUserHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process insert User request"); + handler.processRequest(arg0,arg1); + + } + + @Override + protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { + + GDataRequestHandler handler = HANDLER_FACTORY.getUpdateUserHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process update User request"); + handler.processRequest(arg0,arg1); + } + + + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java (working copy) @@ -18,10 +18,15 @@ import java.io.IOException; +import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; + +import org.apache.lucene.gdata.server.registry.ComponentType; +import org.apache.lucene.gdata.server.registry.GDataServerRegistry; +import org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory; /** * @@ -42,7 +47,9 @@ private static final String METHOD_POST = "POST"; - private static final String METHOD_PUT = "PUT"; + private static final String METHOD_PUT = "PUT"; + + protected static RequestHandlerFactory HANDLER_FACTORY = null; /** * This overwrites the protected service method to dispatch @@ -92,6 +99,17 @@ super.service(arg0, arg1); } + } + + /** + * + * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) + */ + public void init(ServletConfig arg0) throws ServletException { + HANDLER_FACTORY = GDataServerRegistry.getRegistry().lookup(RequestHandlerFactory.class,ComponentType.REQUESTHANDLERFACTORY); + if(HANDLER_FACTORY == null) + throw new ServletException("service not available"); + } } Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java (working copy) @@ -1,104 +1,104 @@ -/** - * Copyright 2004 The Apache Software Foundation +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.GDataRequestException; +import org.apache.lucene.gdata.server.Service; +import org.apache.lucene.gdata.server.ServiceException; +import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; + +/** + * Default Handler implementation. This handler processes the incoming + * {@link org.apache.lucene.gdata.server.GDataRequest} and retrieves the + * requested feed from the underlaying storage. + *

+ * This hander also processes search queries and retrives the search hits from + * the underlaying search component. The user query will be accessed via the + * {@link org.apache.lucene.gdata.server.GDataRequest} instance passed to the + * {@link Service} class. + *

* - * 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 + * @author Simon Willnauer * - * 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.lucene.gdata.servlet.handler; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.gdata.server.GDataRequestException; -import org.apache.lucene.gdata.server.Service; -import org.apache.lucene.gdata.server.ServiceException; -import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; - -import com.google.gdata.data.BaseEntry; -import com.google.gdata.data.BaseFeed; - -/** - * Default Handler implementation. This handler processes the incoming - * {@link org.apache.lucene.gdata.server.GDataRequest} and retrieves the - * requested feed from the underlaying storage. - *

- * This hander also processes search queries and retrives the search hits from - * the underlaying search component. The user query will be accessed via the - * {@link org.apache.lucene.gdata.server.GDataRequest} instance passed to the - * {@link Service} class. - *

- * - * - * @author Simon Willnauer - * - */ -public class DefaultGetHandler extends AbstractGdataRequestHandler { - private static final Log LOG = LogFactory.getLog(DefaultGetHandler.class); - - /** - * @see org.apache.lucene.gdata.servlet.handler.AbstractGdataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - @Override - public void processRequest(HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - try { - initializeRequestHandler(request, response, GDataRequestType.GET); - } catch (GDataRequestException e) { - sendError(); - return; - } - Service service = getService(); - try { - if (LOG.isInfoEnabled()) - LOG.info("Requested output formate: " - + this.feedRequest.getRequestedResponseFormat()); - this.feedResponse.setOutputFormat(this.feedRequest - .getRequestedResponseFormat()); - if(this.feedRequest.isFeedRequested()){ - BaseFeed feed = service - .getFeed(this.feedRequest, this.feedResponse); - - this.feedResponse.sendResponse(feed, this.feedRequest.getExtensionProfile()); - }else{ - BaseEntry entry = service.getSingleEntry(this.feedRequest,this.feedResponse); - if(entry == null){ - this.feedResponse.setError(HttpServletResponse.SC_NOT_FOUND); - sendError(); - } - this.feedResponse.sendResponse(entry, this.feedRequest.getExtensionProfile()); - } - - - } catch (ServiceException e) { // TODO handle exceptions to send exact - // response - LOG.error("Could not process GetFeed request - " + e.getMessage(), - e); - this.feedResponse.setError(HttpServletResponse.SC_BAD_REQUEST); // TODO - // change - // this - sendError(); - } - - - - } - - - -} + */ +public class DefaultGetHandler extends AbstractGdataRequestHandler { + private static final Log LOG = LogFactory.getLog(DefaultGetHandler.class); + + /** + * @see org.apache.lucene.gdata.servlet.handler.AbstractGdataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + public void processRequest(HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + try { + initializeRequestHandler(request, response, GDataRequestType.GET); + } catch (GDataRequestException e) { + sendError(); + return; + } + + try { + if (LOG.isInfoEnabled()) + LOG.info("Requested output formate: " + + this.feedRequest.getRequestedResponseFormat()); + this.feedResponse.setOutputFormat(this.feedRequest + .getRequestedResponseFormat()); + if(this.feedRequest.isFeedRequested()){ + BaseFeed feed = this.service + .getFeed(this.feedRequest, this.feedResponse); + + this.feedResponse.sendResponse(feed, this.feedRequest.getConfigurator().getExtensionProfilClass()); + }else{ + BaseEntry entry = this.service.getSingleEntry(this.feedRequest,this.feedResponse); + if(entry == null){ + this.feedResponse.setError(HttpServletResponse.SC_NOT_FOUND); + sendError(); + } + this.feedResponse.sendResponse(entry, this.feedRequest.getConfigurator().getExtensionProfilClass()); + } + + + } catch (ServiceException e) { // TODO handle exceptions to send exact + // response + LOG.error("Could not process GetFeed request - " + e.getMessage(), + e); + this.feedResponse.setError(HttpServletResponse.SC_BAD_REQUEST); // TODO + // change + // this + sendError(); + } + + + + } + + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (working copy) @@ -1,69 +1,135 @@ -/** - * Copyright 2004 The Apache Software Foundation +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.servlet.handler; + +import org.apache.lucene.gdata.server.registry.Component; +import org.apache.lucene.gdata.server.registry.ComponentType; + +/** + * Default implementation for RequestHandlerFactory Builds the + * {@link org.apache.lucene.gdata.servlet.handler.GDataRequestHandler} + * instances. + * This class should not be access directy. The class will be registered in the {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry}. + * Use {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry#lookup(Class, ComponentType)} * - * 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 + * @author Simon Willnauer * - * 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.lucene.gdata.servlet.handler; - -/** - * Default implementation for RequestHandlerFactory Builds the - * {@link org.apache.lucene.gdata.servlet.handler.GDataRequestHandler} - * instances. - * - * @author Simon Willnauer - * - */ -public class DefaultRequestHandlerFactory extends RequestHandlerFactory { - - DefaultRequestHandlerFactory() { - // - } - - /** - * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getUpdateHandler() - */ - @Override - public GDataRequestHandler getUpdateHandler() { - - return new DefaultUpdateHandler(); - } - - /** - * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getDeleteHandler() - */ - @Override - public GDataRequestHandler getDeleteHandler() { - - return new DefaultDeleteHandler(); - } - - /** - * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getQueryHandler() - */ - @Override - public GDataRequestHandler getQueryHandler() { - - return new DefaultGetHandler(); - } - - /** - * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getInsertHandler() - */ - @Override - public GDataRequestHandler getInsertHandler() { - - return new DefaultInsertHandler(); - } - -} + */ +@Component(componentType=ComponentType.REQUESTHANDLERFACTORY) +public class DefaultRequestHandlerFactory extends RequestHandlerFactory { + + + /** + * public constructor to enable loading via the registry + * @see org.apache.lucene.gdata.server.registry.Component + * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry + */ + public DefaultRequestHandlerFactory() { + // + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getEntryUpdateHandler() + */ + @Override + public GDataRequestHandler getEntryUpdateHandler() { + + return new DefaultUpdateHandler(); + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getEntryDeleteHandler() + */ + @Override + public GDataRequestHandler getEntryDeleteHandler() { + + return new DefaultDeleteHandler(); + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getFeedQueryHandler() + */ + @Override + public GDataRequestHandler getFeedQueryHandler() { + + return new DefaultGetHandler(); + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getEntryInsertHandler() + */ + @Override + public GDataRequestHandler getEntryInsertHandler() { + + return new DefaultInsertHandler(); + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getInsertUserHandler() + */ + @Override + public GDataRequestHandler getInsertUserHandler() { + + return null; + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getDeleteUserHandler() + */ + @Override + public GDataRequestHandler getDeleteUserHandler() { + + return null; + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getUpdateUserHandler() + */ + @Override + public GDataRequestHandler getUpdateUserHandler() { + + return null; + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getInsertFeedHandler() + */ + @Override + public GDataRequestHandler getInsertFeedHandler() { + + return null; + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getUpdateFeedHandler() + */ + @Override + public GDataRequestHandler getUpdateFeedHandler() { + + return null; + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getDeleteFeedHandler() + */ + @Override + public GDataRequestHandler getDeleteFeedHandler() { + + return null; + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java (working copy) @@ -1,84 +1,78 @@ -/** - * Copyright 2004 The Apache Software Foundation - * - * 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.apache.lucene.gdata.servlet.handler; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.gdata.server.FeedNotFoundException; -import org.apache.lucene.gdata.server.GDataRequestException; -import org.apache.lucene.gdata.server.Service; -import org.apache.lucene.gdata.server.ServiceException; -import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; - -/** - * Default Handler implementation. This handler processes the incoming - * {@link org.apache.lucene.gdata.server.GDataRequest} and deletes the requested - * feed entry from the storage and the search component. - *

- * The handler sends following response to the client: - *

- *
    - *
  1. if the entry could be deleted - HTTP status code 200 OK
  2. - *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. - *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. - *
- * - * @author Simon Willnauer - * - */ -public class DefaultDeleteHandler extends AbstractGdataRequestHandler { - private static final Log LOG = LogFactory - .getLog(DefaultDeleteHandler.class); - - /** - * @throws ServletException - * @see org.apache.lucene.gdata.servlet.handler.AbstractGdataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - @Override - public void processRequest(HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - try { - initializeRequestHandler(request, response,GDataRequestType.DELETE); - } catch (GDataRequestException e) { - sendError(); - return; - } - - Service service = getService(); - try { - service.deleteEntry(this.feedRequest, this.feedResponse); - } catch (FeedNotFoundException e) { - LOG.error("Could not process DeleteFeed request Feed Not Found- " - + e.getMessage(), e); - setError(HttpServletResponse.SC_NOT_FOUND); - sendError(); - } catch (ServiceException e) { - LOG.error("Could not process DeleteFeed request - " - + e.getMessage(), e); - setError(HttpServletResponse.SC_BAD_REQUEST); - sendError(); - } - - } - -} +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.GDataRequestException; +import org.apache.lucene.gdata.server.ServiceException; +import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; + +/** + * Default Handler implementation. This handler processes the incoming + * {@link org.apache.lucene.gdata.server.GDataRequest} and deletes the requested + * feed entry from the storage and the search component. + *

+ * The handler sends following response to the client: + *

+ *
    + *
  1. if the entry could be deleted - HTTP status code 200 OK
  2. + *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. + *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. + *
+ * + * @author Simon Willnauer + * + */ +public class DefaultDeleteHandler extends AbstractGdataRequestHandler { + private static final Log LOG = LogFactory + .getLog(DefaultDeleteHandler.class); + + /** + * @throws ServletException + * @see org.apache.lucene.gdata.servlet.handler.AbstractGdataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + public void processRequest(HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + try { + initializeRequestHandler(request, response,GDataRequestType.DELETE); + } catch (GDataRequestException e) { + sendError(); + return; + } + + + try { + this.service.deleteEntry(this.feedRequest, this.feedResponse); + + } catch (ServiceException e) { + LOG.error("Could not process DeleteFeed request - " + + e.getMessage(), e); + setError(HttpServletResponse.SC_BAD_REQUEST); + sendError(); + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java (working copy) @@ -1,94 +1,87 @@ -/** - * Copyright 2004 The Apache Software Foundation - * - * 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.apache.lucene.gdata.servlet.handler; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.gdata.server.FeedNotFoundException; -import org.apache.lucene.gdata.server.GDataRequestException; -import org.apache.lucene.gdata.server.Service; -import org.apache.lucene.gdata.server.ServiceException; -import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; - -import com.google.gdata.data.BaseEntry; - -/** - * Default Handler implementation. This handler processes the incoming - * {@link org.apache.lucene.gdata.server.GDataRequest} and updates the requested - * feed entry in the storage and the search component. - *

- * The handler sends following response to the client: - *

- *
    - *
  1. if the entry was successfully updated - HTTP status code 200 OK
  2. - *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. - *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. - *
- * - * @author Simon Willnauer - * - */ -public class DefaultUpdateHandler extends AbstractGdataRequestHandler { - private static final Log LOG = LogFactory - .getLog(DefaultUpdateHandler.class); - - /** - * @throws ServletException - * @see org.apache.lucene.gdata.servlet.handler.AbstractGdataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - @Override - public void processRequest(HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - try { - initializeRequestHandler(request, response,GDataRequestType.UPDATE); - } catch (GDataRequestException e) { - sendError(); - return; - } - - Service service = getService(); - try { - BaseEntry entry = service.updateEntry(this.feedRequest, - this.feedResponse); - setFeedResponseFormat(); - setFeedResponseStatus(HttpServletResponse.SC_OK); - this.feedResponse.sendResponse(entry, this.feedRequest.getExtensionProfile()); - }catch (FeedNotFoundException e) { - LOG.error("Could not process UpdateFeed request - " - + e.getMessage(), e); - setError(HttpServletResponse.SC_NOT_FOUND); - - sendError(); - } - catch (ServiceException e) { - - LOG.error("Could not process UpdateFeed request - " - + e.getMessage(), e); - setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - - sendError(); - } - - } - -} +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.GDataRequestException; +import org.apache.lucene.gdata.server.ServiceException; +import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; + +import com.google.gdata.data.BaseEntry; + +/** + * Default Handler implementation. This handler processes the incoming + * {@link org.apache.lucene.gdata.server.GDataRequest} and updates the requested + * feed entry in the storage and the search component. + *

+ * The handler sends following response to the client: + *

+ *
    + *
  1. if the entry was successfully updated - HTTP status code 200 OK
  2. + *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. + *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. + *
+ * + * @author Simon Willnauer + * + */ +public class DefaultUpdateHandler extends AbstractGdataRequestHandler { + private static final Log LOG = LogFactory + .getLog(DefaultUpdateHandler.class); + + /** + * @throws ServletException + * @see org.apache.lucene.gdata.servlet.handler.AbstractGdataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + public void processRequest(HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + try { + initializeRequestHandler(request, response,GDataRequestType.UPDATE); + } catch (GDataRequestException e) { + sendError(); + return; + } + + + try { + BaseEntry entry = this.service.updateEntry(this.feedRequest, + this.feedResponse); + setFeedResponseFormat(); + setFeedResponseStatus(HttpServletResponse.SC_OK); + this.feedResponse.sendResponse(entry, this.feedRequest.getConfigurator().getExtensionProfilClass()); + + } + catch (ServiceException e) { + + LOG.error("Could not process UpdateFeed request - " + + e.getMessage(), e); + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + + sendError(); + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java (working copy) @@ -1,83 +1,82 @@ -/** - * Copyright 2004 The Apache Software Foundation +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.GDataRequestException; +import org.apache.lucene.gdata.server.ServiceException; +import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; + +import com.google.gdata.data.BaseEntry; + +/** + * Default Handler implementation. This handler processes the incoming + * {@link org.apache.lucene.gdata.server.GDataRequest} and inserts the requested + * feed entry into the storage and the search component. + *

+ * The handler sends following response to the client: + *

+ *
    + *
  1. if the entry was added - HTTP status code 200 OK
  2. + *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. + *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. + *
+ *

The added entry will be send back to the client if the insert request was successful.

* - * 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.apache.lucene.gdata.servlet.handler; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.gdata.server.GDataRequestException; -import org.apache.lucene.gdata.server.Service; -import org.apache.lucene.gdata.server.ServiceException; -import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; - -import com.google.gdata.data.BaseEntry; - -/** - * Default Handler implementation. This handler processes the incoming - * {@link org.apache.lucene.gdata.server.GDataRequest} and inserts the requested - * feed entry into the storage and the search component. - *

- * The handler sends following response to the client: - *

- *
    - *
  1. if the entry was added - HTTP status code 200 OK
  2. - *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. - *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. - *
- *

The added entry will be send back to the client if the insert request was successful.

- * - * @author Simon Willnauer - * - */ -public class DefaultInsertHandler extends AbstractGdataRequestHandler { - private static final Log LOG = LogFactory.getLog(DefaultInsertHandler.class); - /** - * @throws ServletException - * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ - @Override - public void processRequest(HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - try { - initializeRequestHandler(request,response,GDataRequestType.INSERT); - } catch (GDataRequestException e) { - sendError(); - return; - } - - Service service = getService(); - try{ - BaseEntry entry = service.createEntry(this.feedRequest,this.feedResponse); - setFeedResponseFormat(); - setFeedResponseStatus(HttpServletResponse.SC_CREATED); - this.feedResponse.sendResponse(entry, this.feedRequest.getExtensionProfile()); - - }catch (ServiceException e) { - LOG.error("Could not process GetFeed request - "+e.getMessage(),e); - setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - this.feedResponse.sendError(); - } - - - } - -} + * @author Simon Willnauer + * + */ +public class DefaultInsertHandler extends AbstractGdataRequestHandler { + private static final Log LOG = LogFactory.getLog(DefaultInsertHandler.class); + /** + * @throws ServletException + * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + @Override + public void processRequest(HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + try { + initializeRequestHandler(request,response,GDataRequestType.INSERT); + } catch (GDataRequestException e) { + sendError(); + return; + } + + + try{ + BaseEntry entry = this.service.createEntry(this.feedRequest,this.feedResponse); + setFeedResponseFormat(); + setFeedResponseStatus(HttpServletResponse.SC_CREATED); + this.feedResponse.sendResponse(entry, this.feedRequest.getConfigurator().getExtensionProfilClass()); + + }catch (ServiceException e) { + LOG.error("Could not process GetFeed request - "+e.getMessage(),e); + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + this.feedResponse.sendError(); + } + + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java (working copy) @@ -1,96 +1,100 @@ -/** - * Copyright 2004 The Apache Software Foundation +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.GDataRequest; +import org.apache.lucene.gdata.server.GDataRequestException; +import org.apache.lucene.gdata.server.GDataResponse; +import org.apache.lucene.gdata.server.Service; +import org.apache.lucene.gdata.server.ServiceFactory; +import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; +import org.apache.lucene.gdata.server.registry.ComponentType; +import org.apache.lucene.gdata.server.registry.GDataServerRegistry; + +/** + * @author Simon Willnauer * - * 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.apache.lucene.gdata.servlet.handler; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.gdata.server.GDataRequest; -import org.apache.lucene.gdata.server.GDataRequestException; -import org.apache.lucene.gdata.server.GDataResponse; -import org.apache.lucene.gdata.server.Service; -import org.apache.lucene.gdata.server.ServiceFactory; -import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; - -/** - * @author Simon Willnauer - * - */ -public abstract class AbstractGdataRequestHandler implements - GDataRequestHandler { - private final static Log LOG = LogFactory - .getLog(AbstractGdataRequestHandler.class); - - - protected GDataRequest feedRequest; - protected GDataResponse feedResponse; - - /** - * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, - * javax.servlet.http.HttpServletResponse) - */ - public abstract void processRequest(HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException; - - protected void initializeRequestHandler(final HttpServletRequest request, final HttpServletResponse response, final GDataRequestType type) - throws GDataRequestException { - this.feedRequest = new GDataRequest(request, type); - this.feedResponse = new GDataResponse(response); - try { - this.feedRequest.initializeRequest(); - } catch (GDataRequestException e) { - this.feedResponse.setError(HttpServletResponse.SC_NOT_FOUND); - LOG.warn("Couldn't initialize FeedRequest - " + e.getMessage(), e); - throw e; - } - } - - - - protected void sendError() throws IOException { - this.feedResponse.sendError(); - - } - - protected void setFeedResponseFormat() { - this.feedResponse.setOutputFormat(this.feedRequest.getRequestedResponseFormat()); - } - - protected void setFeedResponseStatus(int status) { - this.feedResponse.setResponseCode(status); - } - - protected void setError(int error) { - this.feedResponse.setError(error); - } - - protected Service getService() throws ServletException { - ServiceFactory serviceFactory = ServiceFactory.getInstance(); - Service service = serviceFactory.getService(); - if(service == null) - throw new ServletException("Service not available"); - return service; - } - - - -} + */ +public abstract class AbstractGdataRequestHandler implements + GDataRequestHandler { + private final static Log LOG = LogFactory + .getLog(AbstractGdataRequestHandler.class); + + protected Service service; + protected GDataRequest feedRequest; + protected GDataResponse feedResponse; + + /** + * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + public abstract void processRequest(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException; + + protected void initializeRequestHandler(final HttpServletRequest request, final HttpServletResponse response, final GDataRequestType type) + throws GDataRequestException, ServletException { + this.feedRequest = new GDataRequest(request, type); + this.feedResponse = new GDataResponse(response); + getService(); + try { + this.feedRequest.initializeRequest(); + } catch (GDataRequestException e) { + this.feedResponse.setError(HttpServletResponse.SC_NOT_FOUND); + LOG.warn("Couldn't initialize FeedRequest - " + e.getMessage(), e); + throw e; + } + } + + + + protected void sendError() throws IOException { + this.feedResponse.sendError(); + + } + + protected void setFeedResponseFormat() { + this.feedResponse.setOutputFormat(this.feedRequest.getRequestedResponseFormat()); + } + + protected void setFeedResponseStatus(int status) { + this.feedResponse.setResponseCode(status); + } + + protected void setError(int error) { + this.feedResponse.setError(error); + } + + private void getService() throws ServletException { + GDataServerRegistry registry = GDataServerRegistry.getRegistry(); + ServiceFactory serviceFactory = registry.lookup(ServiceFactory.class,ComponentType.SERVICEFACTORY); + this.service = serviceFactory.getService(); + if(this.service == null) + throw new ServletException("Service not available"); + + } + + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java (working copy) @@ -1,122 +1,96 @@ -/** - * Copyright 2004 The Apache Software Foundation +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.servlet.handler; + +/** + * Abstract Superclass for RequestHandlerFactories + * @author Simon Willnauer * - * 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.apache.lucene.gdata.servlet.handler; - -/** - * @author Simon Willnauer - * - */ -public abstract class RequestHandlerFactory { - - private static RequestHandlerFactory INSTANCE = null; - - /** - * This method creates a singleton instance of the given type. The fist call - * will create an instance of the given class which will be returned in - * every subsequent call. Any subsequent call to this method will ignore the - * given class object. - * - * @param factoryImplementation - - * the factory implementation (must be a subtype of this Class) - * - * @return - a singleton instance of the given type - * - */ - public static synchronized RequestHandlerFactory getInstance( - Class factoryImplementation) { - if (INSTANCE == null) { - - INSTANCE = createInstance(factoryImplementation); - } - return INSTANCE; - } - - /** - * Singleton - Pattern using private constructor - * - */ - RequestHandlerFactory() { - super(); - - } - - private static RequestHandlerFactory createInstance( - final Class qualifiedClass) { - if (qualifiedClass == null) - throw new IllegalArgumentException( - "Factory class is null -- must be a implementation of org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory"); - try { - return (RequestHandlerFactory) qualifiedClass.newInstance(); - } catch (Exception e) { - FactoryImplementationException ex = new FactoryImplementationException( - "Factory implementation could not be created", e.getCause()); - ex.setStackTrace(e.getStackTrace()); - throw ex; - } - } - - /** - * Creates a UpdateHandler which processes a GDATA UPDATE request. - * @return - an RequestHandlerInstance - */ - public abstract GDataRequestHandler getUpdateHandler(); - - /** - * Creates a DeleteHandler which processes a GDATA DELETE request. - * @return - an RequestHandlerInstance - */ - public abstract GDataRequestHandler getDeleteHandler(); - - /** - * Creates a QueryHandler which processes a GDATA Query / Get request. - * @return - an RequestHandlerInstance - */ - public abstract GDataRequestHandler getQueryHandler(); - - /** - * Creates a InsertHandler which processes a GDATA Insert request. - * @return - an RequestHandlerInstance - */ - public abstract GDataRequestHandler getInsertHandler(); - - - - private static class FactoryImplementationException extends - RuntimeException { - - /** - * - */ - private static final long serialVersionUID = 3166033278825112569L; - - /** - * Constructs a new FactoryImplementationException with the specified - * cause and message - * - * @param arg0 - - * the detail message - * @param arg1 - - * the throw cause - */ - public FactoryImplementationException(String arg0, Throwable arg1) { - super(arg0, arg1); - - } - - } - -} + */ +public abstract class RequestHandlerFactory { + + + + + /** + * public constructor to enable loading via the registry + * @see org.apache.lucene.gdata.server.registry.Component + * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry + */ + public RequestHandlerFactory() { + super(); + + } + + + /** + * Creates a EntryUpdateHandler which processes a GDATA UPDATE request. + * @return - a RequestHandlerInstance + */ + public abstract GDataRequestHandler getEntryUpdateHandler(); + + /** + * Creates a EntryDeleteHandler which processes a GDATA DELETE request. + * @return - a RequestHandlerInstance + */ + public abstract GDataRequestHandler getEntryDeleteHandler(); + + /** + * Creates a FeedQueryHandler which processes a GDATA Query / Get request. + * @return - a RequestHandlerInstance + */ + public abstract GDataRequestHandler getFeedQueryHandler(); + + /** + * Creates a EntryInsertHandler which processes a GDATA Insert request. + * @return - a RequestHandlerInstance + */ + public abstract GDataRequestHandler getEntryInsertHandler(); + /** + * Creates a InsertUserHandler which processes a GDATA Insert request. + * @return - a RequestHandlerInstance + */ + public abstract GDataRequestHandler getInsertUserHandler(); + /** + * Creates a DeleteUserHandler which processes a GDATA Insert request. + * @return - a RequestHandlerInstance + */ + public abstract GDataRequestHandler getDeleteUserHandler(); + /** + * Creates a UpdateUserHandler which processes a GDATA Insert request. + * @return - a RequestHandlerInstance + */ + public abstract GDataRequestHandler getUpdateUserHandler(); + /** + * Creates a InsertFeedHandler which processes a GDATA Insert request. + * @return - a RequestHandlerInstance + */ + public abstract GDataRequestHandler getInsertFeedHandler(); + /** + * Creates a UpdateFeedHandler which processes a GDATA Insert request. + * @return - a RequestHandlerInstance + */ + public abstract GDataRequestHandler getUpdateFeedHandler(); + /** + * Creates a DeleteFeedHandler which processes a GDATA Insert request. + * @return - a RequestHandlerInstance + */ + public abstract GDataRequestHandler getDeleteFeedHandler(); + + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/FeedAdministrationServlet.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/FeedAdministrationServlet.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/FeedAdministrationServlet.java (revision 0) @@ -0,0 +1,71 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.servlet; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.servlet.handler.GDataRequestHandler; + +/** + * This Servlet provides an REST interface to create / update and delete Feed instances. + * + * @author Simon Willnauer + * + */ +public class FeedAdministrationServlet extends AbstractGdataServlet { + private static final Log LOGGER = LogFactory.getLog(FeedAdministrationServlet.class); + /** + * + */ + private static final long serialVersionUID = -905586350743277032L; + + @Override + protected void doDelete(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { + GDataRequestHandler handler = HANDLER_FACTORY.getDeleteFeedHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process delete feed request"); + handler.processRequest(arg0,arg1); + + } + + @Override + protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { + GDataRequestHandler handler = HANDLER_FACTORY.getInsertFeedHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process insert feed request"); + handler.processRequest(arg0,arg1); + + } + + @Override + protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { + GDataRequestHandler handler = HANDLER_FACTORY.getUpdateFeedHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process update feed request"); + handler.processRequest(arg0,arg1); + + } + + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageCoreController.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageCoreController.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageCoreController.java (working copy) @@ -1,286 +1,295 @@ -package org.apache.lucene.gdata.storage.lucenestorage; +package org.apache.lucene.gdata.storage.lucenestorage; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.gdata.server.registry.Component; +import org.apache.lucene.gdata.server.registry.ComponentType; +import org.apache.lucene.gdata.storage.IDGenerator; +import org.apache.lucene.gdata.storage.Storage; +import org.apache.lucene.gdata.storage.StorageController; +import org.apache.lucene.gdata.storage.StorageException; +import org.apache.lucene.gdata.storage.lucenestorage.configuration.StorageConfigurator; +import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter; +import org.apache.lucene.index.IndexModifier; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.FSDirectory; +import org.apache.lucene.store.RAMDirectory; + +/** + * TODO document this + * @author Simon Willnauer + * + */ +@Component(componentType=ComponentType.STORAGECONTROLLER) +public class StorageCoreController implements StorageController{ + protected static final Log LOG = LogFactory.getLog(StorageCoreController.class); + private IndexSearcher searcher; + private final Directory storageDir; + private final StorageModifier modifier; + private ReferenceCounter storageQuery; + private StorageBuffer currentBuffer; + private Object storageControllerLock = new Object(); + private static final int DEFAULT_STORAGE_BUFFER_SIZE = 10; + private static final int DEFAULT_STORAGE_PERSIST_FACTOR = 10; + private static final String STORAGELOG = ".lucenestorage"; + private int storageBufferSize; + private int storagePersistFactor; + private StorageConfigurator configurator; + private IDGenerator idGenerator; + private int indexOptimizeInterval; + + + + + + + /** + * @throws IOException + * @throws StorageException + */ + public StorageCoreController() throws IOException, StorageException { + synchronized (StorageCoreController.class) { + try{ + this.idGenerator = new IDGenerator(10); + }catch (Exception e) { + throw new StorageException("Can't create ID Generator",e); + } + + boolean createNewStorage = false; + this.configurator = StorageConfigurator.getStorageConfigurator(); + if(!this.configurator.isRamDirectory()){ + + String storageDirPath = this.configurator.getStorageDirectory(); + File storeDir = new File(storageDirPath); + File storageLog = new File(storeDir.getAbsolutePath()+System.getProperty("file.separator")+STORAGELOG); + try{ + if(storeDir.isDirectory() && !storageLog.exists()){ + + if(createLuceneStorageLog(storeDir)){ + this.storageDir = FSDirectory.getDirectory(storeDir,true); + createNewStorage = true; + } + else + throw new StorageException("could not create storage log file in "+storageDirPath); + + }else + this.storageDir = FSDirectory.getDirectory(storeDir,false); + }catch (IOException e) { + storageLog.delete(); + throw e; + } + this.indexOptimizeInterval = this.configurator.getIndexOptimizeInterval(); + this.storageBufferSize = this.configurator.getStorageBufferSize() < DEFAULT_STORAGE_BUFFER_SIZE?DEFAULT_STORAGE_BUFFER_SIZE:this.configurator.getStorageBufferSize(); + this.storagePersistFactor = this.configurator.getStoragepersistFactor() < DEFAULT_STORAGE_PERSIST_FACTOR? DEFAULT_STORAGE_PERSIST_FACTOR:this.configurator.getStoragepersistFactor(); + + } + else + this.storageDir = getRamDirectory(); + + this.currentBuffer = new StorageBuffer(this.storageBufferSize); + this.modifier = createStorageModifier(createNewStorage); + this.searcher = new IndexSearcher(this.storageDir); + + + + + + + } + + } + private StorageModifier createStorageModifier(boolean create) throws IOException{ + IndexModifier indexModifier = new IndexModifier(this.storageDir,new StandardAnalyzer(),create); + return new StorageModifier(this,indexModifier,this.currentBuffer,this.storagePersistFactor,this.indexOptimizeInterval); + } + /**TODO document this + * @return + */ + public StorageModifier getStorageModifier(){ + return this.modifier; + } + -import java.io.File; -import java.io.IOException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.gdata.server.registry.GDataServerRegistry; -import org.apache.lucene.gdata.storage.IDGenerator; -import org.apache.lucene.gdata.storage.StorageController; -import org.apache.lucene.gdata.storage.StorageException; -import org.apache.lucene.gdata.storage.lucenestorage.configuration.StorageConfigurator; -import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter; -import org.apache.lucene.index.IndexModifier; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.FSDirectory; - -/** - * TODO document this - * @author Simon Willnauer - * - */ -public class StorageCoreController implements StorageController{ - protected static final Log LOG = LogFactory.getLog(StorageCoreController.class); - private IndexSearcher searcher; - private static StorageCoreController coreController; - private final Directory storageDir; - private final StorageModifier modifier; - private ReferenceCounter storageQuery; - private StorageBuffer currentBuffer; - private Object storageControllerLock = new Object(); - private static final int DEFAULT_STORAGE_BUFFER_SIZE = 10; - private static final int DEFAULT_STORAGE_PERSIST_FACTOR = 10; - private static final String STORAGELOG = ".lucenestorage"; - private int storageBufferSize; - private int storagePersistFactor; - private StorageConfigurator configurator; - private IDGenerator idGenerator; - private int indexOptimizeInterval; - - private StorageCoreController()throws IOException, StorageException{ - this(null); - } + + /**TODO document this + * @return + * @throws IOException + */ + public ReferenceCounter getStorageQuery() throws IOException { + synchronized (this.storageControllerLock) { + + if(this.storageQuery == null){ + this.storageQuery = getNewStorageQueryHolder(new StorageQuery(this.currentBuffer,this.searcher)); + if(LOG.isInfoEnabled()) + LOG.info("Relese new StorageQuery"); + } + this.storageQuery.increamentReference(); + return this.storageQuery; + } + } + private ReferenceCounter getNewStorageQueryHolder(final StorageQuery query){ + ReferenceCounter holder = new ReferenceCounter(query){ + public void close(){ + try{ + if(LOG.isInfoEnabled()) + LOG.info("close StorageQuery -- zero references remaining"); + this.resource.close(); + }catch (IOException e) { + LOG.warn("Error during close call on StorageQuery"+e.getMessage(),e); + } + } + }; + holder.increamentReference(); + return holder; + } + + protected void registerNewStorageQuery() throws IOException{ + if(LOG.isInfoEnabled()) + LOG.info("new StorageQuery requested -- create new storage buffer"); + synchronized (this.storageControllerLock) { + if(this.storageQuery != null) + this.storageQuery.decrementRef(); + this.searcher = new IndexSearcher(this.storageDir); + this.storageQuery = null; + this.currentBuffer = new StorageBuffer(this.storageBufferSize); + + } + + } + - private StorageCoreController(final Directory dir) throws IOException, StorageException { - synchronized (StorageCoreController.class) { - try{ - this.idGenerator = new IDGenerator(10); - }catch (Exception e) { - throw new StorageException("Can't create ID Generator",e); - } - - boolean createNewStorage = false; - - if(dir == null){ - this.configurator = StorageConfigurator.getStorageConfigurator(); - String storageDirPath = this.configurator.getStorageDirectory(); - File storeDir = new File(storageDirPath); - File storageLog = new File(storeDir.getAbsolutePath()+System.getProperty("file.separator")+STORAGELOG); - try{ - if(storeDir.isDirectory() && !storageLog.exists()){ - - if(createLuceneStorageLog(storeDir)){ - this.storageDir = FSDirectory.getDirectory(storeDir,true); - createNewStorage = true; - } - else - throw new StorageException("could not create storage log file in "+storageDirPath); - - }else - this.storageDir = FSDirectory.getDirectory(storeDir,false); - }catch (IOException e) { - storageLog.delete(); - throw e; - } - this.indexOptimizeInterval = this.configurator.getIndexOptimizeInterval(); - this.storageBufferSize = this.configurator.getStorageBufferSize() < DEFAULT_STORAGE_BUFFER_SIZE?DEFAULT_STORAGE_BUFFER_SIZE:this.configurator.getStorageBufferSize(); - this.storagePersistFactor = this.configurator.getStoragepersistFactor() < DEFAULT_STORAGE_PERSIST_FACTOR? DEFAULT_STORAGE_PERSIST_FACTOR:this.configurator.getStoragepersistFactor(); - - } - else - this.storageDir = dir; - - this.currentBuffer = new StorageBuffer(this.storageBufferSize); - this.modifier = createStorageModifier(createNewStorage); - this.searcher = new IndexSearcher(this.storageDir); - - - GDataServerRegistry.getRegistry().registerStorage(this);// TODO reverse dependency here - - - - } - - } - private StorageModifier createStorageModifier(boolean create) throws IOException{ - IndexModifier indexModifier = new IndexModifier(this.storageDir,new StandardAnalyzer(),create); - return new StorageModifier(indexModifier,this.currentBuffer,this.storagePersistFactor,this.indexOptimizeInterval); - } - /**TODO document this - * @return - */ - public StorageModifier getStorageModifier(){ - return this.modifier; - } - - /**TODO document this - * @return - * @throws IOException - * @throws StorageException - */ - public static StorageCoreController getStorageCoreController() throws IOException, StorageException{ - synchronized (StorageCoreController.class) { - if(coreController == null) - coreController = new StorageCoreController(); - return coreController; - } - } - /**TODO document this - * @param dir - * @return - * @throws IOException - * @throws StorageException - */ - protected static StorageCoreController getStorageCoreController(final Directory dir) throws IOException, StorageException{ - synchronized (StorageCoreController.class) { - if(coreController == null) - coreController = new StorageCoreController(dir); - return coreController; - } - } - - /**TODO document this - * @return - * @throws IOException - */ - public ReferenceCounter getStorageQuery() throws IOException { - synchronized (this.storageControllerLock) { - - if(this.storageQuery == null){ - this.storageQuery = getNewStorageQueryHolder(new StorageQuery(this.currentBuffer,this.searcher)); - if(LOG.isInfoEnabled()) - LOG.info("Relese new StorageQuery"); - } - this.storageQuery.increamentReference(); - return this.storageQuery; - } - } - - private ReferenceCounter getNewStorageQueryHolder(final StorageQuery query){ - ReferenceCounter holder = new ReferenceCounter(query){ - public void close(){ - try{ - if(LOG.isInfoEnabled()) - LOG.info("close StorageQuery -- zero references remaining"); - this.resource.close(); - }catch (IOException e) { - LOG.warn("Error during close call on StorageQuery"+e.getMessage(),e); - } - } - }; - holder.increamentReference(); - return holder; - } - + protected StorageBuffer releaseNewStorageBuffer() { + synchronized (this.storageControllerLock) { + return this.currentBuffer; + } + } + + /**TODO document this + * @return + * @throws IOException + */ + public IndexModifier createIndexModifier() throws IOException { + if(LOG.isInfoEnabled()) + LOG.info("new IndexModifier created - release to StorageModifier"); + synchronized (this.storageControllerLock) { + return new IndexModifier(this.storageDir,new StandardAnalyzer(),false); + } + } + + private void close() throws IOException{ + synchronized (this.storageControllerLock) { + if(LOG.isInfoEnabled()) + LOG.info("StorageController has been closed -- server is shutting down -- release all resources"); + if(this.storageQuery != null) + this.storageQuery.decrementRef(); + this.modifier.close(); + //TODO make sure all resources will be released + } + } + /**TODO document this + * @return + */ + public int getStorageBufferSize() { + return this.storageBufferSize; + } + /** + * @param storageBufferSize + */ + public void setStorageBufferSize(int storageBufferSize) { + this.storageBufferSize = storageBufferSize; + } + /**TODO document this + * @return + */ + public int getStoragePersistFactor() { + return this.storagePersistFactor; + } + /** + * @param storagePersistFactor + */ + public void setStoragePersistFactor(int storagePersistFactor) { + this.storagePersistFactor = storagePersistFactor; + } + /** + * @throws IOException + * @throws StorageException + */ + public void forceWrite()throws IOException, StorageException{ + this.modifier.forceWrite(); + } + + + private boolean createLuceneStorageLog(File storageDirectory) throws IOException{ + if(storageDirectory.isDirectory() && !storageDirectory.exists()){ + storageDirectory.createNewFile(); + } + File file = new File(storageDirectory.getAbsolutePath()+System.getProperty("file.separator")+STORAGELOG); + return file.createNewFile(); + + + } + - - protected void registerNewStorageQuery() throws IOException{ - if(LOG.isInfoEnabled()) - LOG.info("new StorageQuery requested -- create new storage buffer"); - synchronized (this.storageControllerLock) { - if(this.storageQuery != null) - this.storageQuery.decrementRef(); - this.searcher = new IndexSearcher(this.storageDir); - this.storageQuery = null; - this.currentBuffer = new StorageBuffer(this.storageBufferSize); - - } - - } - - - protected StorageBuffer releaseNewStorageBuffer() { - synchronized (this.storageControllerLock) { - return this.currentBuffer; - } - } - - /**TODO document this - * @return - * @throws IOException - */ - public IndexModifier createIndexModifier() throws IOException { - if(LOG.isInfoEnabled()) - LOG.info("new IndexModifier created - release to StorageModifier"); - synchronized (this.storageControllerLock) { - return new IndexModifier(this.storageDir,new StandardAnalyzer(),false); - } - } - - private void close() throws IOException{ - synchronized (this.storageControllerLock) { - if(LOG.isInfoEnabled()) - LOG.info("StorageController has been closed -- server is shutting down -- release all resources"); - if(this.storageQuery != null) - this.storageQuery.decrementRef(); - coreController = null; - this.modifier.close(); - //TODO make sure all resources will be released - } - } - /**TODO document this - * @return - */ - public int getStorageBufferSize() { - return this.storageBufferSize; - } - /** - * @param storageBufferSize - */ - public void setStorageBufferSize(int storageBufferSize) { - this.storageBufferSize = storageBufferSize; - } - /**TODO document this - * @return - */ - public int getStoragePersistFactor() { - return this.storagePersistFactor; - } - /** - * @param storagePersistFactor - */ - public void setStoragePersistFactor(int storagePersistFactor) { - this.storagePersistFactor = storagePersistFactor; - } - /** - * @throws IOException - * @throws StorageException - */ - public void forceWrite()throws IOException, StorageException{ - this.modifier.forceWrite(); - } - - - private boolean createLuceneStorageLog(File storageDirectory) throws IOException{ - if(storageDirectory.isDirectory() && !storageDirectory.exists()){ - storageDirectory.createNewFile(); - } - File file = new File(storageDirectory.getAbsolutePath()+System.getProperty("file.separator")+STORAGELOG); - return file.createNewFile(); - - - } - + /**TODO document this + * @return + * @throws StorageException + */ + public synchronized String releaseID() throws StorageException{ + try{ + return this.idGenerator.getUID(); + }catch (InterruptedException e) { + throw new StorageException("Can't release new ID",e); + } + + } + + + + /** + * @see org.apache.lucene.gdata.storage.StorageController#destroy() + */ + public void destroy() { + try{ + close(); + }catch (Exception e) { + LOG.error("Closing StorageCoreController failed -- "+e.getMessage(),e); + } + } - /**TODO document this - * @return - * @throws StorageException - */ - public synchronized String releaseID() throws StorageException{ - try{ - return this.idGenerator.getUID(); - }catch (InterruptedException e) { - throw new StorageException("Can't release new ID",e); + protected Directory getDirectory(){ + return this.storageDir; + } + + /** + * @see org.apache.lucene.gdata.storage.StorageController#getStorage() + */ + public Storage getStorage()throws StorageException{ + try { + return new StorageImplementation(); + } catch (StorageException e) { + StorageException ex = new StorageException("Can't create Storage instance -- " + + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } - - } - - - - /** - * @see org.apache.lucene.gdata.storage.StorageController#destroy() - */ - public void destroy() { - try{ - close(); - }catch (Exception e) { - LOG.error("Closing StorageCoreController failed -- "+e.getMessage(),e); - } - } -} + } + //TODO Try to remove this + private RAMDirectory getRamDirectory() throws IOException{ + IndexWriter writer; + RAMDirectory retVal = new RAMDirectory(); + writer = new IndexWriter(retVal,new StandardAnalyzer(),true); + writer.close(); + return retVal; + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageModifier.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageModifier.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageModifier.java (working copy) @@ -1,236 +1,440 @@ -package org.apache.lucene.gdata.storage.lucenestorage; - -import java.io.IOException; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.document.Document; -import org.apache.lucene.gdata.storage.StorageException; -import org.apache.lucene.index.IndexModifier; -import org.apache.lucene.index.Term; - -/** - * TODO document this - * @author Simon Willnauer +package org.apache.lucene.gdata.storage.lucenestorage; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.document.Document; +import org.apache.lucene.gdata.storage.StorageException; +import org.apache.lucene.index.IndexModifier; +import org.apache.lucene.index.Term; + +/** + * The StorageModifier is the a Singleton component of the LuceneStorage. There + * is one single instance of this class modifying the index used to store all + * the gdata Entities as Entries, Feeds and Users. This class contains an + * instance of {@link org.apache.lucene.index.IndexModifier} used to manage all + * delete and add actions to the storage. + *

+ * To prevent the storage component from opening and closing the + * {@link org.apache.lucene.index.IndexModifier} for every modifying operation + * the incoming entry actions (DELETE, UPDATE, INSERT) will be buffered in a + * registered instance of + * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer}. When a + * certain amout (specified as the persistfactor in the configuration file) of + * modifications have been executed the StorageModifier will persist the + * buffered entries. + *

+ *

+ * Feed and User operations won't be buffered. These actions occure not very + * often compared to entry actions. Every call of an user / feed modifying + * operation forces all changes to be written to the storage index. + *

* - */ -public class StorageModifier { - protected static final Log LOG = LogFactory.getLog(StorageModifier.class); - - private final List deletedDocumentQueue; - private final List deletedForUpdateDocumentQueue; - - private final Map documentMap; - - - private volatile int persistFactor; - - private volatile int modifiedCounter = 0; - - private static int DEFAULT_PERSIST_FACTOR = 10; - - private StorageBuffer buffer; - - private IndexModifier modifier; - - private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false); - - private Lock readLock = this.lock.readLock(); - - private Lock writeLock = this.lock.writeLock(); - private final static int DEFAULT_OPTIMIZE_INTERVAL = 10; - private final int optimizeInterval; - private int optimizeCounter = 0; - - /** - * TODO document this - * @param modifier - * @param buffer - * @param persitsFactor - * @param optimizeInterval - */ - public StorageModifier(final IndexModifier modifier, - final StorageBuffer buffer, int persitsFactor,int optimizeInterval) { - this.deletedDocumentQueue = new LinkedList(); - this.deletedForUpdateDocumentQueue = new LinkedList(); - this.documentMap = new HashMap(persitsFactor); - this.buffer = buffer; - - this.persistFactor = persitsFactor > 0 ? persitsFactor - : DEFAULT_PERSIST_FACTOR; - this.modifier = modifier; - this.optimizeInterval = optimizeInterval < DEFAULT_OPTIMIZE_INTERVAL?DEFAULT_OPTIMIZE_INTERVAL:optimizeInterval; - - } - - /** - * TODO document this - * @param wrapper - * @throws StorageException - */ - public void updateEntry(StorageEntryWrapper wrapper) - throws StorageException { - try { - this.readLock.lock(); - Term tempTerm = new Term(StorageEntryWrapper.FIELD_ENTRY_ID, wrapper.getEntryId()); - this.buffer.addEntry(wrapper); - this.deletedForUpdateDocumentQueue.add(tempTerm); - this.documentMap.put(wrapper.getEntryId(),wrapper.getLuceneDocument()); - storageModified(); - } finally { - this.readLock.unlock(); - } - } - - /** - * TODO document this - * @param wrapper - * @throws StorageException - */ - public void insertEntry(StorageEntryWrapper wrapper) throws StorageException { - this.readLock.lock(); - try { - - this.buffer.addEntry(wrapper); - this.documentMap.put(wrapper.getEntryId(),wrapper.getLuceneDocument()); - storageModified(); - } finally { - this.readLock.unlock(); - } - } - - /** - *TODO document this - * @param entryId - * @param feedId - * @throws StorageException + * @author Simon Willnauer + * + */ +public class StorageModifier { + protected static final Log LOG = LogFactory.getLog(StorageModifier.class); + + private final List deletedDocumentQueue; + + private final List deletedForUpdateDocumentQueue; + + private final Map documentMap; + + private final List forceWriteDocuments; + + private final List forceWriteTerms; + + private volatile int persistFactor; + + private volatile int modifiedCounter = 0; + + private static int DEFAULT_PERSIST_FACTOR = 10; + + private StorageBuffer buffer; + + private IndexModifier modifier; + + private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false); + + private Lock readLock = this.lock.readLock(); + + private Lock writeLock = this.lock.writeLock(); + + private final static int DEFAULT_OPTIMIZE_INTERVAL = 10; + + private final int optimizeInterval; + + private volatile int optimizeCounter = 0; + + private final StorageCoreController controller; + + /** + * Creates a new StorageModifier * - */ - public void deleteEntry(final String entryId, final String feedId) throws StorageException { - try { - this.readLock.lock(); - Term tempTerm = new Term(StorageEntryWrapper.FIELD_ENTRY_ID, entryId); - this.buffer.addDeleted(entryId, feedId); - this.deletedDocumentQueue.add(tempTerm); - storageModified(); - } finally { - this.readLock.unlock(); - } - } - - private void storageModified() throws StorageException { - this.readLock.unlock(); - this.writeLock.lock(); - - try { - incrementCounter(); - if (this.persistFactor > this.modifiedCounter) - return; - - if (LOG.isInfoEnabled()) - LOG.info("Storage modified for " + this.modifiedCounter - + " times. Write Persistent index"); - writePersistentIndex((this.optimizeCounter >= this.optimizeInterval)); - requestNewIndexModifier(); - - this.modifiedCounter = 0; - } catch (IOException e) { - LOG.error("Writing persistent index failed - Recovering", e); - } finally { - this.readLock.lock(); - this.writeLock.unlock(); - } - - } - - protected void forceWrite() throws IOException, StorageException { - this.writeLock.lock(); - try { - if (LOG.isInfoEnabled()) - LOG.info("ForceWrite called -- current modifiedCounter: " - + this.modifiedCounter + " - persisting changes"); - writePersistentIndex(true); - requestNewIndexModifier(); - this.modifiedCounter = 0; - } finally { - this.writeLock.unlock(); - } - } - - private void requestNewIndexModifier() throws IOException, StorageException { - StorageCoreController controller = StorageCoreController - .getStorageCoreController(); - controller.registerNewStorageQuery(); - this.buffer = controller.releaseNewStorageBuffer(); - this.modifier = controller.createIndexModifier(); - } - - private void writePersistentIndex(final boolean optimize) throws IOException { - try { - /* - * first delete all updated documents - */ - for(Term entryIdTerm : this.deletedForUpdateDocumentQueue) { - this.modifier.deleteDocuments(entryIdTerm); - } - /* - * add all documents - */ - Collection documents = this.documentMap.values(); - for (Document doc : documents) { - this.modifier.addDocument(doc); - } - /* - * delete all documents marked as deleted. As the DocumentIDs are - * unique the document marked as deleted must not persist after the - * index has been written. - * In the case of an update of a document and a previous delete the concurrency component will not allow an update. - * new inserted entries can not be deleted accidently- - */ - for (Term entryIdTerm : this.deletedDocumentQueue) { - this.modifier.deleteDocuments(entryIdTerm); - } - this.modifier.flush(); - if(optimize){ - if(LOG.isInfoEnabled()) - LOG.info("Optimizing index -- optimize interval "+this.optimizeInterval); - this.modifier.optimize(); - } - - } finally { - if(optimize) - this.optimizeCounter = 0; - this.modifier.close(); - this.deletedForUpdateDocumentQueue.clear(); - this.deletedDocumentQueue.clear(); - this.documentMap.clear(); - } - } - - protected void close()throws IOException{ - this.writeLock.lock(); - try { - if (LOG.isInfoEnabled()) - LOG.info("ForceWrite called -- current modifiedCounter: " - + this.modifiedCounter + " - persisting changes"); - - writePersistentIndex(true); - this.modifiedCounter = 0; - } finally { - this.writeLock.unlock(); - } - } - - private void incrementCounter(){ - this.optimizeCounter++; - this.modifiedCounter++; - } - -} + * @param controller - + * the registered StorageController + * @param modifier - + * the IndexModifier + * @param buffer - + * the StorageBuffer + * @param persitsFactor - + * the factor when the changes will be persisted to the storage + * index + * @param optimizeInterval - + * after how many storage operations the index will be optimized + */ + protected StorageModifier(final StorageCoreController controller, + final IndexModifier modifier, final StorageBuffer buffer, + int persitsFactor, int optimizeInterval) { + this.deletedDocumentQueue = new LinkedList(); + this.deletedForUpdateDocumentQueue = new LinkedList(); + this.documentMap = new HashMap(persitsFactor); + this.forceWriteDocuments = new ArrayList(5); + this.forceWriteTerms = new ArrayList(5); + this.buffer = buffer; + this.controller = controller; + + this.persistFactor = persitsFactor > 0 ? persitsFactor + : DEFAULT_PERSIST_FACTOR; + this.modifier = modifier; + this.optimizeInterval = optimizeInterval < DEFAULT_OPTIMIZE_INTERVAL ? DEFAULT_OPTIMIZE_INTERVAL + : optimizeInterval; + + } + + /** + * Updates the given entry. First the alredy persisted entry will be + * removed, after marking as deleted the new Entry will be written. + * + * @param wrapper - + * the wrapper containing the entry + * @throws StorageException - + * if the entry can not be stored + */ + public void updateEntry(StorageEntryWrapper wrapper) + throws StorageException { + this.readLock.lock(); + try { + Term tempTerm = new Term(StorageEntryWrapper.FIELD_ENTRY_ID, + wrapper.getEntryId()); + this.buffer.addEntry(wrapper); + this.deletedForUpdateDocumentQueue.add(tempTerm); + this.documentMap.put(wrapper.getEntryId(), wrapper + .getLuceneDocument()); + storageModified(); + } finally { + this.readLock.unlock(); + } + } + + /** + * Inserts a new Entry to the Lucene index storage + * + * @param wrapper - + * the wrapper containing the entry + * @throws StorageException - + * if the entry can not be stored + */ + public void insertEntry(StorageEntryWrapper wrapper) + throws StorageException { + this.readLock.lock(); + try { + + this.buffer.addEntry(wrapper); + this.documentMap.put(wrapper.getEntryId(), wrapper + .getLuceneDocument()); + storageModified(); + } finally { + this.readLock.unlock(); + } + } + + /** + * Deletes the entry for the given entry id. + * + * @param entryId - + * the entry id coresponding to the entry to delete + * @param feedId - + * the id of the feed containig the entry + * @throws StorageException - + * if the entry can not be deleted + * + */ + public void deleteEntry(final String entryId, final String feedId) + throws StorageException { + this.readLock.lock(); + try { + Term tempTerm = new Term(StorageEntryWrapper.FIELD_ENTRY_ID, + entryId); + this.buffer.addDeleted(entryId, feedId); + this.deletedDocumentQueue.add(tempTerm); + storageModified(); + } finally { + this.readLock.unlock(); + } + } + + /** + * Adds a new Feed to the storage. Feed action will be not buffered. Call to + * this method forces the index to be written. + * + * @param wrapper - + * the wrapper containing the feed; + * @throws StorageException - + * if the feed can not be written + */ + public void createFeed(StorageFeedWrapper wrapper) throws StorageException { + this.readLock.lock(); + try { + this.forceWriteDocuments.add(wrapper.getLuceneDocument()); + storageModified(); + } finally { + this.readLock.unlock(); + } + } + + /** + * Adds a new User to the storage. User action will be not buffered. Call to + * this method forces the index to be written. + * + * @param user + * -the wrapper containig the user to be persisted + * @throws StorageException - + * if the user can not be persisted. + */ + public void createUser(StorageUserWrapper user) throws StorageException { + this.readLock.lock(); + try { + this.forceWriteDocuments.add(user.getLuceneDocument()); + storageModified(); + } finally { + this.readLock.unlock(); + } + } + + /** + * Deletes the user with the given username. User action will be not + * buffered. Call to this method forces the index to be written. + * + * @param username - + * the user to be deleted + * @throws StorageException - + * If the user could not be deleted + */ + public void deleteUser(String username) throws StorageException { + this.readLock.lock(); + try { + this.forceWriteTerms.add(new Term( + StorageUserWrapper.FIELD_USERNAME, username)); + storageModified(); + } finally { + this.readLock.unlock(); + } + } + + /** + * User action will be not buffered. Call to this method forces the index to + * be written. + * + * @param user + * -the wrapper containig the user to be persisted + * @throws StorageException - + * if the user can not be persisted. + */ + public void updateUser(final StorageUserWrapper user) + throws StorageException { + this.readLock.lock(); + try { + this.forceWriteTerms.add(new Term( + StorageUserWrapper.FIELD_USERNAME, user.getUser() + .getUsername())); + this.forceWriteDocuments.add(user.getLuceneDocument()); + storageModified(); + } finally { + this.readLock.unlock(); + } + } + + /** + * Feed action will be not buffered. Call to this method forces the index to + * be written. + * + * @param wrapper - + * the wrapper containig the feed + * @throws StorageException - + * if the feed can not be persisted + */ + public void updateFeed(final StorageFeedWrapper wrapper) + throws StorageException { + this.readLock.lock(); + try { + this.forceWriteTerms.add(new Term(StorageFeedWrapper.FIELD_FEED_ID, + wrapper.getFeed().getId())); + this.forceWriteDocuments.add(wrapper.getLuceneDocument()); + storageModified(); + } finally { + this.readLock.unlock(); + } + } + + /** + * Deletes the feed with the given feed id Feed action will be not buffered. + * Call to this method forces the index to be written. + * + * @param feedId - + * the id of the feed to delete + * @throws StorageException - + * if the feed can not be deleted + */ + public void deleteFeed(final String feedId) throws StorageException { + this.readLock.lock(); + try { + this.forceWriteTerms.add(new Term(StorageFeedWrapper.FIELD_FEED_ID, + feedId)); + + storageModified(); + } finally { + this.readLock.unlock(); + } + } + + private void storageModified() throws StorageException { + this.readLock.unlock(); + this.writeLock.lock(); + + try { + incrementCounter(); + if (this.persistFactor > this.modifiedCounter + && this.forceWriteDocuments.size() <= 0 + && this.forceWriteTerms.size() <= 0) + return; + + if (LOG.isInfoEnabled()) + LOG.info("Storage modified for " + this.modifiedCounter + + " times. Write Persistent index"); + writePersistentIndex((this.optimizeCounter >= this.optimizeInterval)); + requestNewIndexModifier(); + + this.modifiedCounter = 0; + } catch (IOException e) { + + LOG.error("Writing persistent index failed - Recovering", e); + throw new StorageException("could not write to storage index -- "+e.getMessage(),e); + + } finally { + this.readLock.lock(); + this.writeLock.unlock(); + } + + } + + protected void forceWrite() throws IOException { + this.writeLock.lock(); + try { + if (LOG.isInfoEnabled()) + LOG.info("ForceWrite called -- current modifiedCounter: " + + this.modifiedCounter + " - persisting changes"); + writePersistentIndex(true); + requestNewIndexModifier(); + this.modifiedCounter = 0; + } finally { + this.writeLock.unlock(); + } + } + + private void requestNewIndexModifier() throws IOException { + + this.controller.registerNewStorageQuery(); + this.buffer = this.controller.releaseNewStorageBuffer(); + this.modifier = this.controller.createIndexModifier(); + } + + private void writePersistentIndex(final boolean optimize) + throws IOException { + try { + + /* + * first delete all updated documents + */ + for (Term entryIdTerm : this.deletedForUpdateDocumentQueue) { + this.modifier.deleteDocuments(entryIdTerm); + } + + for (Term term : this.forceWriteTerms) { + this.modifier.deleteDocuments(term); + } + /* + * add all documents + */ + Collection documents = this.documentMap.values(); + for (Document doc : documents) { + this.modifier.addDocument(doc); + } + /* + * write all users or feeds + */ + for (Document docs : this.forceWriteDocuments) { + this.modifier.addDocument(docs); + } + + /* + * delete all documents marked as deleted. As the DocumentIDs are + * unique the document marked as deleted must not persist after the + * index has been written. In the case of an update of a document + * and a previous delete the concurrency component will not allow an + * update. new inserted entries can not be deleted accidently- + */ + for (Term entryIdTerm : this.deletedDocumentQueue) { + this.modifier.deleteDocuments(entryIdTerm); + } + this.modifier.flush(); + if (optimize) { + if (LOG.isInfoEnabled()) + LOG.info("Optimizing index -- optimize interval " + + this.optimizeInterval); + this.modifier.optimize(); + } + + } finally { + if (optimize) + this.optimizeCounter = 0; + this.modifier.close(); + this.deletedForUpdateDocumentQueue.clear(); + this.deletedDocumentQueue.clear(); + this.documentMap.clear(); + this.forceWriteDocuments.clear(); + this.forceWriteTerms.clear(); + } + } + + protected void close() throws IOException { + this.writeLock.lock(); + try { + if (LOG.isInfoEnabled()) + LOG.info("ForceWrite called -- current modifiedCounter: " + + this.modifiedCounter + " - persisting changes"); + + writePersistentIndex(true); + this.modifiedCounter = 0; + } finally { + this.writeLock.unlock(); + } + } + + private void incrementCounter() { + this.optimizeCounter++; + this.modifiedCounter++; + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageUserWrapper.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageUserWrapper.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageUserWrapper.java (revision 0) @@ -0,0 +1,109 @@ +package org.apache.lucene.gdata.storage.lucenestorage; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.gdata.data.GDataUser; + +/** + * Wrapps a User Object. + * The wrapper provides also a Lucene repesentation of the user; + * User Objects will not be Buffered in the lucene storage component. Each User will be written imidialtely. + * @author Simon Willnauer + * + */ +public class StorageUserWrapper implements StorageWrapper{ + private static final Log LOG = LogFactory.getLog(StorageUserWrapper.class); + + /** + * Lucene field for the username + */ + public static final String FIELD_USERNAME = "userName"; + /** + * Lucene field for the password + */ + public static final String FIELD_PASSWORD = "passwd"; + /** + * Lucene field for the author name + */ + public static final String FIELD_AUTHORNAME = "author"; + /** + * Lucene field for the author mail address + */ + public static final String FIELD_AUTHORMAIL = "authorMail"; + /** + * Lucene field for the author link + */ + public static final String FIELD_AUTHORHREF = "authorHref"; + /** + * Lucene field fot the userroles + */ + public static final String FIELD_ROLES = "userroles"; + private final GDataUser user; + /** + * @param user - the user to be wrapped + */ + public StorageUserWrapper(final GDataUser user) { + if(user == null) + throw new IllegalArgumentException("user must not be null"); + this.user = user; + } + + /** + * @see org.apache.lucene.gdata.storage.lucenestorage.StorageWrapper#getLuceneDocument() + */ + public Document getLuceneDocument() { + Document doc = new Document(); + + doc.add(new Field(FIELD_USERNAME,this.user.getUsername(),Field.Store.YES,Field.Index.UN_TOKENIZED)); + doc.add(new Field(FIELD_PASSWORD,this.user.getPassword()==null?"":this.user.getPassword(),Field.Store.YES,Field.Index.NO)); + doc.add(new Field(FIELD_AUTHORNAME,this.user.getAuthorname()==null?"":this.user.getAuthorname(),Field.Store.YES,Field.Index.NO)); + doc.add(new Field(FIELD_AUTHORMAIL,this.user.getAuthorMail()==null?"":this.user.getAuthorMail(),Field.Store.YES,Field.Index.NO)); + doc.add(new Field(FIELD_AUTHORHREF,this.user.getAuthorLink()==null?"":this.user.getAuthorLink().toString(),Field.Store.YES,Field.Index.NO)); + doc.add(new Field(FIELD_ROLES, Integer.toString(this.user.getRolesAsInt()),Field.Store.YES,Field.Index.NO)); + + return doc; + } + + + + + /** + * @param doc - a lucene document representation of an user + * @return - the user to build from the document. or null if the document is null + */ + public static GDataUser buildEntity(final Document doc){ + if(doc == null) + return null; + + GDataUser user = new GDataUser(doc.get(FIELD_USERNAME)); + user.setPassword(doc.get(FIELD_PASSWORD)); + user.setAuthorname(doc.get(FIELD_AUTHORNAME)); + user.setAuthorMail(doc.get(FIELD_AUTHORMAIL)); + try{ + user.setRolesAsInt(Integer.parseInt(doc.get(FIELD_ROLES))); + }catch (NumberFormatException e) { + LOG.info("Can't parse userroles: "+user.getUsername()+" throws NumberFormatException. -- skipping --",e); + } + try { + user.setAuthorLink(new URL(doc.get(FIELD_AUTHORHREF))); + } catch (MalformedURLException e) { + LOG.info("SPECIFIED URL for user: "+user.getUsername()+" throws MalformedURLException. -- skipping --",e); + } + return user; + } + + + + /** + * @return - the wrapped user + */ + public GDataUser getUser() { + return this.user; + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageWrapper.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageWrapper.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageWrapper.java (revision 0) @@ -0,0 +1,31 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.storage.lucenestorage; + +import org.apache.lucene.document.Document; + +/** + * @author Simon Willnauer + * + */ +public interface StorageWrapper { + /** + * Returns a Lucene document representing the Wrapped Entry + * @return a Lucene Document + */ + public abstract Document getLuceneDocument(); +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageEntryWrapper.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageEntryWrapper.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageEntryWrapper.java (working copy) @@ -16,16 +16,16 @@ package org.apache.lucene.gdata.storage.lucenestorage; -import java.io.IOException; -import java.io.StringWriter; +import java.io.IOException; +import java.io.StringWriter; + +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.util.common.xml.XmlWriter; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; - -import com.google.gdata.data.BaseEntry; -import com.google.gdata.data.ExtensionProfile; -import com.google.gdata.util.common.xml.XmlWriter; - /** * This immutable class wrapps Entries for an internal Storage representation of * an entry. This class also acts as a Documentfactory for lucene documents to @@ -34,7 +34,10 @@ * @author Simon Willnauer * */ -public class StorageEntryWrapper implements Comparable { +public class StorageEntryWrapper implements Comparable , StorageWrapper{ + + private static final long serialVersionUID = -4619985652059888526L; + private static final String INTERNAL_ENCODING = "UTF-8"; /** @@ -45,7 +48,7 @@ /** * lucene field name feed id */ - public final static String FIELD_FEED_ID = "feedId"; + public final static String FIELD_FEED_REFERENCE = "feedReference"; /** * lucene field name entry content @@ -71,7 +74,7 @@ private StorageOperation operation; - private final ExtensionProfile profile; + private final FeedInstanceConfigurator config; /** * Creates a new StorageEntryWrapper. @@ -82,19 +85,19 @@ * the feed id * @param operation - * the StorageOperation - * @param profile - - * the ExtensionProfil for the given entry + * @param config - the FeedInstanceConfigurator containing the ExtensionProfil for the given entry * @throws IOException - * if the entry content can not be generated */ - protected StorageEntryWrapper(final BaseEntry entry, final String feedId, - StorageOperation operation, final ExtensionProfile profile) - throws IOException { + public StorageEntryWrapper(final BaseEntry entry, final String feedId, + StorageOperation operation, final FeedInstanceConfigurator config) + throws IOException { + this.entry = entry; this.operation = operation; this.entryId = entry.getId(); this.feedId = feedId; - this.profile = profile; + this.config = config; this.content = buildContent(); this.timestamp = new Long(System.currentTimeMillis()); @@ -103,25 +106,26 @@ private String buildContent() throws IOException { StringWriter writer = new StringWriter(); XmlWriter xmlWriter = new XmlWriter(writer, INTERNAL_ENCODING); - this.entry.generateAtom(xmlWriter, this.profile); + this.entry.generateAtom(xmlWriter, this.config.getExtensionProfilClass()); return writer.toString(); } - /** - * @return - the lucene document representing the entry - */ + + /** + * @see org.apache.lucene.gdata.storage.lucenestorage.StorageWrapper#getLuceneDocument() + */ public Document getLuceneDocument() { if (this.document != null) return this.document; this.document = new Document(); - this.document.add(new Field("entryId", this.entryId, Field.Store.YES, + this.document.add(new Field(FIELD_ENTRY_ID, this.entryId, Field.Store.YES, Field.Index.UN_TOKENIZED)); - this.document.add(new Field("feedId", this.feedId, Field.Store.YES, + this.document.add(new Field(FIELD_FEED_REFERENCE, this.feedId, Field.Store.YES, Field.Index.UN_TOKENIZED)); - this.document.add(new Field("content", this.content, - Field.Store.COMPRESS, Field.Index.UN_TOKENIZED)); - this.document.add(new Field("timestamp", this.timestamp.toString(), + this.document.add(new Field(FIELD_CONTENT, this.content, + Field.Store.COMPRESS, Field.Index.NO)); + this.document.add(new Field(FIELD_TIMESTAMP, this.timestamp.toString(), Field.Store.YES, Field.Index.UN_TOKENIZED)); return this.document; Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/StorageConfigurator.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/StorageConfigurator.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/StorageConfigurator.java (working copy) @@ -1,144 +1,155 @@ -/** - * Copyright 2004 The Apache Software Foundation +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.storage.lucenestorage.configuration; + +import java.io.InputStream; +import java.util.Properties; + +/** + * This clas loads the Storage configuration file and sets all properties. If + * the properties can not be loaded an {@link java.lang.Error} will be thrown. + * The configuration file lucenestorage.properties.xml should be available in the classpath. * - * 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 + * @author Simon Willnauer * - * 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.lucene.gdata.storage.lucenestorage.configuration; - -import java.io.InputStream; -import java.util.Properties; - -/** - * This clas loads the Storage configuration file and sets all properties. If - * the properties can not be loaded an {@link java.lang.Error} will be thrown. - * The configuration file lucenestorage.properties.xml should be available in the classpath. - * - * @author Simon Willnauer - * - */ -public class StorageConfigurator { - private final int storageBufferSize; - - private final int storagepersistFactor; - - private final String storageDirectory; - - private final boolean keepRecoveredFiles; - - private final boolean recover; - - private static StorageConfigurator INSTANCE = null; - - private final int indexOptimizeInterval; - - private StorageConfigurator() { - InputStream stream = StorageConfigurator.class - .getResourceAsStream("/lucenestorage.properties.xml"); - Properties properties = new Properties(); - try { - properties.loadFromXML(stream); - - } catch (Exception e) { - throw new StorageConfigurationError("Could not load properties", e); - } - this.storageBufferSize = Integer.parseInt(properties - .getProperty("gdata.server.storage.lucene.buffersize")); - this.storagepersistFactor = Integer.parseInt(properties - .getProperty("gdata.server.storage.lucene.persistFactor")); - this.recover = Boolean.parseBoolean(properties - .getProperty("gdata.server.storage.lucene.recover")); - this.keepRecoveredFiles = Boolean.parseBoolean(properties - .getProperty("gdata.server.storage.lucene.recover.keepFiles")); - this.storageDirectory = properties - .getProperty("gdata.server.storage.lucene.directory"); - this.indexOptimizeInterval = Integer.parseInt(properties - .getProperty("gdata.server.storage.lucene.optimizeInterval")); - - } - - /** - * @return - the storage configurator - */ - public static synchronized StorageConfigurator getStorageConfigurator() { - if (INSTANCE == null) - INSTANCE = new StorageConfigurator(); - return INSTANCE; - } - - /** - * Keep recovering files. -- will use a lot of disk space - * - * @return true if the storage is supposed to keep the - * recovering files. - */ - public boolean isKeepRecoveredFiles() { - return this.keepRecoveredFiles; - } - - /** - * @return true if the storage is supposed to use recovering. - * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier - */ - public boolean isRecover() { - return this.recover; - } - - /** - * @return - the configured storage buffer size - * @see org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer - */ - public int getStorageBufferSize() { - return this.storageBufferSize; - } - - /** - * @return - the configured storage directory - * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier - */ - public String getStorageDirectory() { - return this.storageDirectory; - } - - /** - * @return - the persist factor - * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier - */ - public int getStoragepersistFactor() { - return this.storagepersistFactor; - } - - protected class StorageConfigurationError extends Error { - - /** - * - */ - private static final long serialVersionUID = 5261674332036111464L; - - protected StorageConfigurationError(String arg0, Throwable arg1) { - super(arg0, arg1); - - } - - } - - /** - * @return - the optimize interval - * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier - */ - public int getIndexOptimizeInterval() { - - return this.indexOptimizeInterval; - } - -} + */ +public class StorageConfigurator { + private final int storageBufferSize; + + private final int storagepersistFactor; + + private final String storageDirectory; + + private final boolean keepRecoveredFiles; + + private final boolean recover; + + private final boolean ramDirectory; + + private static StorageConfigurator INSTANCE = null; + + private final int indexOptimizeInterval; + + private StorageConfigurator() { + InputStream stream = StorageConfigurator.class + .getResourceAsStream("/lucenestorage.properties.xml"); + Properties properties = new Properties(); + try { + properties.loadFromXML(stream); + + } catch (Exception e) { + throw new StorageConfigurationError("Could not load properties", e); + } + this.storageBufferSize = Integer.parseInt(properties + .getProperty("gdata.server.storage.lucene.buffersize")); + this.storagepersistFactor = Integer.parseInt(properties + .getProperty("gdata.server.storage.lucene.persistFactor")); + this.recover = Boolean.parseBoolean(properties + .getProperty("gdata.server.storage.lucene.recover")); + this.ramDirectory = Boolean.parseBoolean(properties + .getProperty("gdata.server.storage.lucene.directory.ramDirectory")); + this.keepRecoveredFiles = Boolean.parseBoolean(properties + .getProperty("gdata.server.storage.lucene.recover.keepFiles")); + this.storageDirectory = properties + .getProperty("gdata.server.storage.lucene.directory"); + this.indexOptimizeInterval = Integer.parseInt(properties + .getProperty("gdata.server.storage.lucene.optimizeInterval")); + + } + + /** + * @return - the storage configurator + */ + public static synchronized StorageConfigurator getStorageConfigurator() { + if (INSTANCE == null) + INSTANCE = new StorageConfigurator(); + return INSTANCE; + } + + /** + * Keep recovering files. -- will use a lot of disk space + * + * @return true if the storage is supposed to keep the + * recovering files. + */ + public boolean isKeepRecoveredFiles() { + return this.keepRecoveredFiles; + } + + /** + * @return true if the storage is supposed to use recovering. + * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier + */ + public boolean isRecover() { + return this.recover; + } + + /** + * @return - the configured storage buffer size + * @see org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer + */ + public int getStorageBufferSize() { + return this.storageBufferSize; + } + + /** + * @return - the configured storage directory + * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier + */ + public String getStorageDirectory() { + return this.storageDirectory; + } + + /** + * @return - the persist factor + * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier + */ + public int getStoragepersistFactor() { + return this.storagepersistFactor; + } + + protected class StorageConfigurationError extends Error { + + /** + * + */ + private static final long serialVersionUID = 5261674332036111464L; + + protected StorageConfigurationError(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + } + + /** + * @return - the optimize interval + * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier + */ + public int getIndexOptimizeInterval() { + + return this.indexOptimizeInterval; + } + + /** + * @return true if the used directory is a ramdirectory, otherwise false + */ + public boolean isRamDirectory() { + return this.ramDirectory; + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageFeedWrapper.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageFeedWrapper.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageFeedWrapper.java (revision 0) @@ -0,0 +1,95 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.storage.lucenestorage; + +import java.io.IOException; +import java.io.StringWriter; + +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; + +import com.google.gdata.data.BaseFeed; +import com.google.gdata.util.common.xml.XmlWriter; + +/** + * @author Simon Willnauer + * + */ +public class StorageFeedWrapper implements StorageWrapper { + + private static final String INTERNAL_ENCODING = "UTF-8"; + /** + * the username who owns the feed + */ + public static final String FIELD_USERNAME = "userReference"; + /** + * the id of the feed + */ + public static final String FIELD_FEED_ID = "feedId"; + /** + * The xml feed representation + */ + public static final String FIELD_CONTENT = "content"; + /** + * The typ of the feed e.g. the class name of the feed instance + */ + public static final String FIELD_FEED_TYPE = "feedType"; + private final BaseFeed feed; + private final String username; + private final FeedInstanceConfigurator config; + private final String content; + + /** + * @param feed + * @param username + * @param config + * @throws IOException + * + */ + public StorageFeedWrapper(final BaseFeed feed, final String username, final FeedInstanceConfigurator config) throws IOException { + this.feed = feed; + this.username = username; + this.config = config; + this.content = buildContent(); + } + + /** + * @see org.apache.lucene.gdata.storage.lucenestorage.StorageWrapper#getLuceneDocument() + */ + public Document getLuceneDocument() { + Document doc = new Document(); + doc.add(new Field(FIELD_USERNAME,this.username,Field.Store.YES,Field.Index.UN_TOKENIZED)); + doc.add(new Field(FIELD_FEED_ID,this.feed.getId(),Field.Store.YES,Field.Index.UN_TOKENIZED)); + doc.add(new Field(FIELD_CONTENT,this.content,Field.Store.COMPRESS,Field.Index.NO)); + doc.add(new Field(FIELD_FEED_TYPE,this.feed.getClass().getName(),Field.Store.YES,Field.Index.NO)); + return doc; + } + + private String buildContent() throws IOException { + StringWriter writer = new StringWriter(); + XmlWriter xmlWriter = new XmlWriter(writer, INTERNAL_ENCODING); + this.feed.generateAtom(xmlWriter,this.config.getExtensionProfilClass()); + return writer.toString(); + } + /** + * @return - the wrapped feed + */ + public BaseFeed getFeed(){ + return this.feed; + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageImplementation.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageImplementation.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageImplementation.java (working copy) @@ -1,259 +1,442 @@ -/** - * Copyright 2004 The Apache Software Foundation +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.storage.lucenestorage; + +import java.io.IOException; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.data.GDataUser; +import org.apache.lucene.gdata.server.registry.ComponentType; +import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; +import org.apache.lucene.gdata.server.registry.GDataServerRegistry; +import org.apache.lucene.gdata.storage.Storage; +import org.apache.lucene.gdata.storage.StorageController; +import org.apache.lucene.gdata.storage.StorageException; +import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation; +import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; + +/** + * This is an implementation of the + * {@link org.apache.lucene.gdata.storage.Storage} interface. The + * StorageImplementation provides access to the + * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageQuery} and the + * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageModifier}. This + * class will be instanciated per client request. * - * 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.apache.lucene.gdata.storage.lucenestorage; - -import java.io.IOException; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.gdata.storage.Storage; -import org.apache.lucene.gdata.storage.StorageException; -import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation; -import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter; - -import com.google.gdata.data.BaseEntry; -import com.google.gdata.data.BaseFeed; -import com.google.gdata.data.ExtensionProfile; -import com.google.gdata.data.Feed; - -/** - * This is an implementation of the - * {@link org.apache.lucene.gdata.storage.Storage} interface. The - * StorageImplementation provides access to the - * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageQuery} and the - * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageModifier}. This - * class will be instanciated per client request. - * - * - * - * @author Simon Willnauer - * - */ -public class StorageImplementation implements Storage { - private final StorageCoreController controller; - - private ExtensionProfile profile; - - private static final Log LOG = LogFactory - .getLog(StorageImplementation.class); - - /** - * Creates a new StorageImplementation - * - * @throws StorageException - - * if the - * {@link org.apache.lucene.gdata.storage.StorageController} can - * not be created - * @throws IOException - - * if the - * {@link org.apache.lucene.gdata.storage.StorageController} can - * not be created - * @see StorageCoreController#getStorageCoreController() - * - */ - public StorageImplementation() throws IOException, StorageException { - this.controller = StorageCoreController.getStorageCoreController(); - } - - /** - * @see org.apache.lucene.gdata.storage.Storage#storeEntry(com.google.gdata.data.BaseEntry, - * java.lang.String) - */ - public BaseEntry storeEntry(BaseEntry entry, String feedId) - throws StorageException { - if (this.profile == null) - throw new StorageException( - "Can process ExtensionProfile not set -- is null"); - if (feedId == null) - throw new StorageException("No feed ID specified -- is null"); - StorageModifier modifier = this.controller.getStorageModifier(); - String id = this.controller.releaseID(); - entry.setId(feedId + id); - if (LOG.isInfoEnabled()) - LOG.info("Store entry " + id + " -- feed: " + feedId); - - try { - StorageEntryWrapper wrapper = new StorageEntryWrapper(entry, - feedId, StorageOperation.INSERT, this.profile); - modifier.insertEntry(wrapper); - } catch (IOException e) { - StorageException ex = new StorageException("Can't create Entry -- " - + e.getMessage(), e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - + * @author Simon Willnauer + * + */ +public class StorageImplementation implements Storage { + private final StorageCoreController controller; + + private FeedInstanceConfigurator config; + + private static final Log LOG = LogFactory + .getLog(StorageImplementation.class); + + /** + * Creates a new StorageImplementation + * @throws StorageException - if the storage controller can not be obtained + * + * + * + */ + public StorageImplementation() throws StorageException { + this.controller = (StorageCoreController)GDataServerRegistry.getRegistry().lookup(StorageController.class,ComponentType.STORAGECONTROLLER); + if(this.controller == null) + throw new StorageException("Can't get registered StorageController"); + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#storeEntry(com.google.gdata.data.BaseEntry, + * java.lang.String) + */ + public BaseEntry storeEntry(BaseEntry entry, String feedId) + throws StorageException { + if (this.config == null) + throw new StorageException( + "Can process ExtensionProfile not set -- is null"); + if (feedId == null) + throw new StorageException("No feed ID specified -- is null"); + StorageModifier modifier = this.controller.getStorageModifier(); + String id = this.controller.releaseID(); + entry.setId(feedId + id); + if (LOG.isInfoEnabled()) + LOG.info("Store entry " + id + " -- feed: " + feedId); + + try { + StorageEntryWrapper wrapper = new StorageEntryWrapper(entry, + feedId, StorageOperation.INSERT, this.config); + modifier.insertEntry(wrapper); + } catch (IOException e) { + StorageException ex = new StorageException("Can't create Entry -- " + + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + + } + + return entry; + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#deleteEntry(java.lang.String, + * java.lang.String) + */ + public void deleteEntry(String entryId, String feedId) + throws StorageException { + if (this.config == null) + throw new StorageException( + "Can process ExtensionProfile not set -- is null"); + if (feedId == null) + throw new StorageException("No feed ID specified -- is null"); + if (entryId == null) + throw new StorageException("No entry ID specified -- is null"); + if (LOG.isInfoEnabled()) + LOG.info("delete entry " + entryId + " -- feed: " + feedId); + StorageModifier modifier = this.controller.getStorageModifier(); + modifier.deleteEntry(entryId, feedId); + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#updateEntry(com.google.gdata.data.BaseEntry, + * java.lang.String) + */ + public BaseEntry updateEntry(BaseEntry entry, String feedId) + throws StorageException { + if (this.config == null) + throw new StorageException( + "Can process ExtensionProfile not set -- is null"); + if (feedId == null) + throw new StorageException("No feed ID specified -- is null"); + if (entry == null) + throw new StorageException("enrty is null"); + if (entry.getId() == null) + throw new StorageException("No entry ID specified -- is null"); + if (LOG.isInfoEnabled()) + LOG.info("update entry " + entry.getId() + " -- feed: " + feedId); + StorageModifier modifier = this.controller.getStorageModifier(); + + try { + StorageEntryWrapper wrapper = new StorageEntryWrapper(entry, + feedId, StorageOperation.UPDATE, this.config); + modifier.updateEntry(wrapper); + } catch (IOException e) { + LOG.error("Can't update entry for feedID: " + feedId + + "; entryId: " + entry.getId() + " -- " + e.getMessage(), + e); + StorageException ex = new StorageException("Can't create Entry -- " + + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + + } + + return entry; + + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#getFeed(java.lang.String, + * int, int) + */ + @SuppressWarnings("unchecked") + public BaseFeed getFeed(String feedId, int startIndex, int resultCount) + throws StorageException { + if (this.config == null) + throw new StorageException( + "Can process ExtensionProfile not set -- is null"); + if (feedId == null) + throw new StorageException("No feed ID specified -- is null"); + if (LOG.isInfoEnabled()) + LOG.info("get feed: " + feedId + " startindex: " + startIndex + + " resultCount: " + resultCount); + ReferenceCounter query = null; + try { + query = this.controller.getStorageQuery(); + BaseFeed feed = query.get().getLatestFeedQuery(feedId, + resultCount, startIndex, this.config); + return feed; + } catch (Exception e) { + LOG.error("Can't get latest feed for feedID: " + feedId + " -- " + + e.getMessage(), e); + StorageException ex = new StorageException("Can't create Entry -- " + + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + + } finally { + if (query != null) + query.decrementRef(); + } + + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#getEntry(java.lang.String, + * java.lang.String) + */ + public BaseEntry getEntry(String entryId, String feedId) + throws StorageException { + if (this.config == null) + throw new StorageException( + "Can process ExtensionProfile not set -- is null"); + if (feedId == null) + throw new StorageException("No feed ID specified -- is null"); + if (entryId == null) + throw new StorageException("No entry ID specified -- is null"); + if (LOG.isInfoEnabled()) + LOG.info("get entry " + entryId + " -- feed: " + feedId); + ReferenceCounter query = null; + try { + query = this.controller.getStorageQuery(); + return query.get().singleEntryQuery(entryId, feedId, this.config); + } catch (Exception e) { + LOG.error("Can't get entry for feedID: " + feedId + "; entryId: " + + entryId + " -- " + e.getMessage(), e); + StorageException ex = new StorageException("Can't create Entry -- " + + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + + } finally { + if (query != null) + query.decrementRef(); + } + + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#getEntries(java.util.List, + * java.lang.String) + */ + public List getEntries(List entryIdList, String feedId) + throws StorageException { + throw new StorageException("not implemented yet"); + // TODO implement this + + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#close() + */ + public void close() { + // + } + + + /** + * @see org.apache.lucene.gdata.storage.Storage#setFeedInstanceConfig(org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator) + */ + public void setFeedInstanceConfig(final FeedInstanceConfigurator config) { + this.config = config; + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#saveUser(org.apache.lucene.gdata.data.GDataUser) + */ + public void saveUser(GDataUser user) throws StorageException { + if(user == null) + throw new StorageException("Can not save null user"); + ReferenceCounter query = null; + try { + query = this.controller.getStorageQuery(); + if(query.get().getUser(user.getUsername()) != null) + throw new StorageException("user already exists"); + StorageModifier modifier = this.controller.getStorageModifier(); + StorageUserWrapper wrapper = new StorageUserWrapper(user); + modifier.createUser(wrapper); + } catch (Exception e) { + LOG.error("Can't save user -- "+ e.getMessage(), e); + StorageException ex = new StorageException("Can't save user -- " + + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + + } finally { + if (query != null) + query.decrementRef(); + } + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#updateUser(org.apache.lucene.gdata.data.GDataUser) + */ + public void updateUser(GDataUser user) throws StorageException { + if(user == null) + throw new StorageException("Can not update null user"); + ReferenceCounter query = null; + try { + query = this.controller.getStorageQuery(); + if(query.get().getUser(user.getUsername()) == null) + throw new StorageException("user does not exist"); + StorageModifier modifier = this.controller.getStorageModifier(); + StorageUserWrapper wrapper = new StorageUserWrapper(user); + modifier.updateUser(wrapper); + } catch (Exception e) { + LOG.error("Can't update user -- "+ e.getMessage(), e); + StorageException ex = new StorageException("Can't update user -- " + + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + + } finally { + if (query != null) + query.decrementRef(); + } + + + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#deleteUser(java.lang.String) + */ + public void deleteUser(String username) throws StorageException { + if(username == null) + throw new StorageException("can not delete null user"); + ReferenceCounter query = null; + try { + query = this.controller.getStorageQuery(); + if(query.get().getUser(username) == null) + throw new StorageException("user does not exist"); + StorageModifier modifier = this.controller.getStorageModifier(); + modifier.deleteUser(username); + } catch (Exception e) { + LOG.error("Can't update user -- "+ e.getMessage(), e); + StorageException ex = new StorageException("Can't update user -- " + + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + + } finally { + if (query != null) + query.decrementRef(); + } + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#insertFeed(com.google.gdata.data.BaseFeed, java.lang.String) + */ + public void insertFeed(BaseFeed feed, String username) throws StorageException { + if(feed == null) + throw new StorageException("can not insert null feed"); + if(username == null) + throw new StorageException("username must not be null"); + try { + StorageModifier modifier = this.controller.getStorageModifier(); + StorageFeedWrapper wrapper = new StorageFeedWrapper(feed,username,this.config); + modifier.createFeed(wrapper); + + } catch (Exception e) { + LOG.error("Can't create feed -- "+ e.getMessage(), e); + StorageException ex = new StorageException("Can't create feed -- " + + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } - - return entry; - } - - /** - * @see org.apache.lucene.gdata.storage.Storage#deleteEntry(java.lang.String, - * java.lang.String) - */ - public void deleteEntry(String entryId, String feedId) - throws StorageException { - if (this.profile == null) - throw new StorageException( - "Can process ExtensionProfile not set -- is null"); - if (feedId == null) - throw new StorageException("No feed ID specified -- is null"); - if (entryId == null) - throw new StorageException("No entry ID specified -- is null"); - if (LOG.isInfoEnabled()) - LOG.info("delete entry " + entryId + " -- feed: " + feedId); - StorageModifier modifier = this.controller.getStorageModifier(); - modifier.deleteEntry(entryId, feedId); - } - - /** - * @see org.apache.lucene.gdata.storage.Storage#updateEntry(com.google.gdata.data.BaseEntry, - * java.lang.String) - */ - public BaseEntry updateEntry(BaseEntry entry, String feedId) - throws StorageException { - if (this.profile == null) - throw new StorageException( - "Can process ExtensionProfile not set -- is null"); - if (feedId == null) - throw new StorageException("No feed ID specified -- is null"); - if (entry == null) - throw new StorageException("enrty is null"); - if (entry.getId() == null) - throw new StorageException("No entry ID specified -- is null"); - if (LOG.isInfoEnabled()) - LOG.info("update entry " + entry.getId() + " -- feed: " + feedId); - StorageModifier modifier = this.controller.getStorageModifier(); - - try { - StorageEntryWrapper wrapper = new StorageEntryWrapper(entry, - feedId, StorageOperation.UPDATE, this.profile); - modifier.updateEntry(wrapper); - } catch (IOException e) { - LOG.error("Can't update entry for feedID: " + feedId - + "; entryId: " + entry.getId() + " -- " + e.getMessage(), - e); - StorageException ex = new StorageException("Can't create Entry -- " - + e.getMessage(), e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - - } - - return entry; - - } - - /** - * @see org.apache.lucene.gdata.storage.Storage#getFeed(java.lang.String, - * int, int) - */ - @SuppressWarnings("unchecked") - public BaseFeed getFeed(String feedId, int startIndex, int resultCount) - throws StorageException { - if (this.profile == null) - throw new StorageException( - "Can process ExtensionProfile not set -- is null"); - if (feedId == null) - throw new StorageException("No feed ID specified -- is null"); - if (LOG.isInfoEnabled()) - LOG.info("get feed: " + feedId + " startindex: " + startIndex - + " resultCount: " + resultCount); - ReferenceCounter query = null; - try { - query = this.controller.getStorageQuery(); - List resultList = query.get().getLatestFeedQuery(feedId, - resultCount, startIndex, this.profile); - BaseFeed feed = new Feed(); - feed.getEntries().addAll(resultList); - return feed; - } catch (Exception e) { - LOG.error("Can't get latest feed for feedID: " + feedId + " -- " - + e.getMessage(), e); - StorageException ex = new StorageException("Can't create Entry -- " - + e.getMessage(), e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - - } finally { - if (query != null) - query.decrementRef(); - } - - } - - /** - * @see org.apache.lucene.gdata.storage.Storage#getEntry(java.lang.String, - * java.lang.String) - */ - public BaseEntry getEntry(String entryId, String feedId) - throws StorageException { - if (this.profile == null) - throw new StorageException( - "Can process ExtensionProfile not set -- is null"); - if (feedId == null) - throw new StorageException("No feed ID specified -- is null"); - if (entryId == null) - throw new StorageException("No entry ID specified -- is null"); - if (LOG.isInfoEnabled()) - LOG.info("get entry " + entryId + " -- feed: " + feedId); - ReferenceCounter query = null; - try { - query = this.controller.getStorageQuery(); - return query.get().singleEntryQuery(entryId, feedId, this.profile); - } catch (Exception e) { - LOG.error("Can't get entry for feedID: " + feedId + "; entryId: " - + entryId + " -- " + e.getMessage(), e); - StorageException ex = new StorageException("Can't create Entry -- " - + e.getMessage(), e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - - } finally { - if (query != null) - query.decrementRef(); - } - - } - - /** - * @see org.apache.lucene.gdata.storage.Storage#getEntries(java.util.List, - * java.lang.String) - */ - public List getEntries(List entryIdList, String feedId) - throws StorageException { - throw new StorageException("not implemented yet"); - // TODO implement this - - } - - /** - * @see org.apache.lucene.gdata.storage.Storage#close() - */ - public void close() { - // - } - - /** - * @see org.apache.lucene.gdata.storage.Storage#setExtensionProfile(com.google.gdata.data.ExtensionProfile) - */ - public void setExtensionProfile(ExtensionProfile profile) { - this.profile = profile; - } - -} + + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#deleteFeed(java.lang.String) + */ + public void deleteFeed(String feedId) throws StorageException { + if(feedId == null) + throw new StorageException("can not delete feed id is null "); + ReferenceCounter query = null; + try { + query = this.controller.getStorageQuery(); + if(query.get().isFeedStored(feedId)) + throw new StorageException("user does not exist"); + StorageModifier modifier = this.controller.getStorageModifier(); + + modifier.deleteFeed(feedId); + + } catch (Exception e) { + LOG.error("Can't create feed -- "+ e.getMessage(), e); + StorageException ex = new StorageException("Can't create feed -- " + + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + + } finally{ + if(query == null) + query.decrementRef(); + } + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#updateFeed(com.google.gdata.data.BaseFeed, java.lang.String) + */ + public void updateFeed(BaseFeed feed, String username) throws StorageException { + if(feed == null) + throw new StorageException("can not update null feed"); + if(username == null) + throw new StorageException("username must not be null"); + ReferenceCounter query = null; + try { + query = this.controller.getStorageQuery(); + if(query.get().isFeedStored(feed.getId())) + throw new StorageException("user does not exist"); + StorageModifier modifier = this.controller.getStorageModifier(); + StorageFeedWrapper wrapper = new StorageFeedWrapper(feed,username,this.config); + modifier.updateFeed(wrapper); + + } catch (Exception e) { + LOG.error("Can't create feed -- "+ e.getMessage(), e); + StorageException ex = new StorageException("Can't create feed -- " + + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + + } finally{ + if(query == null) + query.decrementRef(); + } + + } + + /** + * @see org.apache.lucene.gdata.storage.Storage#getFeedType(java.lang.String) + */ + public String getFeedType(String feedID) throws StorageException { + if(feedID == null) + throw new StorageException("no feed for the feedID == null"); + ReferenceCounter query = null; + try{ + query = this.controller.getStorageQuery(); + String type = query.get().getFeedType(feedID); + if(type == null) + throw new StorageException("no feed for the feedID == "+feedID+" found"); + return type; + }catch (Exception e) { + throw new StorageException("Can not access storage",e); + }finally{ + if(query != null) + query.decrementRef(); + } + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageQuery.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageQuery.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageQuery.java (working copy) @@ -12,331 +12,413 @@ * 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.lucene.gdata.storage.lucenestorage; - -import java.io.IOException; -import java.io.StringReader; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.apache.lucene.document.Document; -import org.apache.lucene.gdata.server.FeedNotFoundException; -import org.apache.lucene.gdata.server.GDataEntityBuilder; -import org.apache.lucene.index.Term; -import org.apache.lucene.search.BooleanClause; -import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.search.Hit; -import org.apache.lucene.search.Hits; -import org.apache.lucene.search.Searcher; -import org.apache.lucene.search.Sort; -import org.apache.lucene.search.SortField; -import org.apache.lucene.search.TermQuery; -import org.apache.lucene.search.BooleanClause.Occur; - -import com.google.gdata.data.BaseEntry; -import com.google.gdata.data.ExtensionProfile; -import com.google.gdata.util.ParseException; - -/** - * StorageQuery wrapps a Lucene {@link org.apache.lucene.search.IndexSearcher} - * and a {@link org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer} to - * perform all request on the lucene storage. - * The wrapped components are thread - safe. - *

- * An instance of this class will serve all client requests. To obtain the - * current instance of the {@link StorageQuery} the method - * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#getStorageQuery()} - * has to be invoked. This method will release the current StorageQuery. - *

- * @see org.apache.lucene.search.IndexSearcher - * @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController - * @see org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer - * - * @author Simon Willnauer - * - */ -public class StorageQuery { - private final StorageBuffer buffer; - - private final Searcher searcher; - - /* - * Sort the result by timestamp desc - */ - private final Sort timeStampSort = new Sort(new SortField(StorageEntryWrapper.FIELD_TIMESTAMP, - SortField.STRING, true)); - - /** - * Creates a new StorageQuery - * - * @param buffer - - * the buffer instance to get the buffered inserts, updates from. - * @param searcher - - * the searcher instance to use to query the storage index. - * - * - */ - protected StorageQuery(final StorageBuffer buffer, final Searcher searcher) { - - this.buffer = buffer; - this.searcher = searcher; - - } - - private Hits storageQuery(List entryId) throws IOException { - BooleanQuery query = new BooleanQuery(); - /* - * query the index using a BooleanQuery - */ - for (String id : entryId) { - TermQuery termQuery = new TermQuery(new Term( - StorageEntryWrapper.FIELD_ENTRY_ID, id)); - // use an OR query - query.add(new BooleanClause(termQuery, Occur.SHOULD)); - } - - return this.searcher.search(query, new ModifiedEntryFilter(this.buffer - .getExculdList())); - } - - /* - * query the storage index for a entire feed. - */ - private Hits storageFeedQuery(final String feedId, final Sort sort) - throws IOException { - TermQuery query = new TermQuery(new Term(StorageEntryWrapper.FIELD_FEED_ID, feedId)); - return this.searcher.search(query, new ModifiedEntryFilter(this.buffer - .getExculdList()), sort); - - } - - /* - * get a single entry - */ - private Hits storageQuery(String entryId) throws IOException { - TermQuery termQuery = new TermQuery(new Term( - StorageEntryWrapper.FIELD_ENTRY_ID, entryId)); - /* - * Filter entries inside the buffer, buffered entries might contain - * deleted entries. These entries must be found!! - */ - return this.searcher.search(termQuery, new ModifiedEntryFilter( - this.buffer.getExculdList())); - - } - - /** - * This method fetches the latest feed entries from the storage. Feed - * ususaly requested via a search query or as a simple query to the REST - * interface. - *

- * The REST interface requestes all the entries from a Storage. The Storage - * retrieves the entries corresponding to the parameters specified. This - * method first requests the latest entries or updated entries from the - * {@link StorageBuffer}. If the buffer already contains enought entries - * for the the specified result count the entires will be returned. If not, - * the underlaying lucene index will be searcher for all documents of the - * specified feed sorted by storing timestamp desc. - *

- *

- * The entries will be searched in a feed context specified by the given - * feed ID - *

- * - * - * @param feedId - - * the requested feed, this id will be used to retrieve the - * entries. - * @param resultCount - - * how many entries are requested - * @param startIndex - - * the offset of the entriy to start from. - * @param profil - - * the extension profile used to create the entriy instances - * @return - an ordered list of {@link BaseEntry} objects, or an empty list - * if no entries could be found - * @throws IOException - - * if the index could not be queries or the entries could not be - * build - * @throws FeedNotFoundException - - * if the requested feed is not registered - * @throws ParseException - - * if an entry could not be parsed while building it from the - * Lucene Document. - */ - // TODO check input parameter - public List getLatestFeedQuery(final String feedId, - final int resultCount, final int startIndex, - final ExtensionProfile profil) throws IOException, - FeedNotFoundException, ParseException { - List returnList = new ArrayList(resultCount); - List bufferedWrapperList = this.buffer - .getSortedEntries(feedId); - int alreadyAdded = 0; - int offset = startIndex - 1; - if (bufferedWrapperList != null - && bufferedWrapperList.size() >= startIndex) { - - for (; alreadyAdded < resultCount; alreadyAdded++) { - if ((bufferedWrapperList.size() - offset) > 0) { - StorageEntryWrapper wrappedEntry = bufferedWrapperList - .get(offset++); - returnList.add(wrappedEntry.getEntry()); - } else - break; - } - // reset offset - offset = startIndex - 1; - if (alreadyAdded == resultCount) - return returnList; - } else { - /* - * if the buffersize is less than the startindex the buffersize must - * be considered. Sublists would not be a repeatable read part of - * the whole list - */ - if (bufferedWrapperList != null) - offset = startIndex - 1 - bufferedWrapperList.size(); - } - - Hits hits = storageFeedQuery(feedId, this.timeStampSort); - if (hits.length() > 0) { - - for (; (offset < hits.length()) && (alreadyAdded < resultCount); offset++, alreadyAdded++) { - Document doc = hits.doc(offset); - BaseEntry entry = buildEntryFromLuceneDocument(doc, profil); - returnList.add(entry); - } - - } - return returnList; - } - - /** - * This method retrieves a single entry from the storage. If the - * {@link StorageBuffer} does not contain the requested entry the - * underlaying storage index will be searched. - *

- * The Entry will be searched in a feed context specified by the given feed - * ID - *

- * - * @param entryId - - * the entry to fetch - * @param feedId - - * the feedid eg. feed context - * @param profil - - * the extension profile used to create the entriy instances - * @return - the requested {@link BaseEntry} or null if the - * entry can not be found - * @throws IOException - - * if the index could not be queries or the entries could not be - * build - * @throws FeedNotFoundException - - * if the requested feed is not registered - * @throws ParseException - - * if an entry could not be parsed while building it from the - * Lucene Document. - */ - public BaseEntry singleEntryQuery(final String entryId, - final String feedId, final ExtensionProfile profil) - throws IOException, FeedNotFoundException, ParseException { - StorageEntryWrapper wrapper = this.buffer.getEntry(entryId, feedId); - - if (wrapper == null) { - Hits hits = storageQuery(entryId); - if (hits.length() <= 0) - return null; - Document doc = hits.doc(0); - - return buildEntryFromLuceneDocument(doc, profil); - } - return wrapper.getEntry(); - - } - - /** - * Fetches the requested entries from the storage. The given list contains - * entry ids to be looked up in the storage. First the {@link StorageBuffer} - * will be queried for the entry ids. If not all of the entries remain in - * the buffer the underlaying lucene index will be searched. The entries are - * not guaranteed to be in the same order as they are in the given id list. - * Entry ID's not found in the index or the buffer will be omitted. - *

- * The entries will be searched in a feed context specified by the given - * feed ID - *

- * - * @param entryIds - - * the entriy ids to fetch. - * @param feedId - - * the feed id eg. feed context. - * @param profil - - * the extension profile used to create the entry instances. - * @return - the list of entries corresponding to the given entry id list. - * @throws IOException - - * if the index could not be queries or the entries could not be - * build - * @throws FeedNotFoundException - - * if the requested feed is not registered - * @throws ParseException - - * if an entry could not be parsed while building it from the - * Lucene Document. - */ - public List entryQuery(List entryIds, - final String feedId, final ExtensionProfile profil) - throws IOException, FeedNotFoundException, ParseException { - List resultList = new ArrayList(entryIds.size()); - List searchList = new ArrayList(entryIds.size()); - for (String entry : entryIds) { - - StorageEntryWrapper bufferedEntry = this.buffer.getEntry(entry, - feedId); - if (bufferedEntry != null) { - resultList.add(bufferedEntry.getEntry()); - } else - searchList.add(entry); - } - if (searchList.isEmpty()) - return resultList; - - Hits hits = storageQuery(searchList); - Iterator hitIterator = hits.iterator(); - while (hitIterator.hasNext()) { - Hit hit = (Hit) hitIterator.next(); - Document doc = hit.getDocument(); - BaseEntry entry = buildEntryFromLuceneDocument(doc, profil); - resultList.add(entry); - - } - - return resultList; - - } - - private BaseEntry buildEntryFromLuceneDocument(final Document doc, - final ExtensionProfile profil) throws FeedNotFoundException, - ParseException, IOException { - StringReader reader = new StringReader(doc.getField(StorageEntryWrapper.FIELD_CONTENT) - .stringValue()); - return GDataEntityBuilder.buildEntry(doc.getField(StorageEntryWrapper.FIELD_FEED_ID) - .stringValue(), reader, profil); - - } - - /** - * Closes all resources used in the {@link StorageQuery}. The instance can - * not be reused after invoking this method. - * - * @throws IOException - - * if the resouces can not be closed - */ - public void close() throws IOException { - this.searcher.close(); - this.buffer.close(); - } - -} + */ + +package org.apache.lucene.gdata.storage.lucenestorage; + +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.lucene.document.Document; +import org.apache.lucene.gdata.data.GDataUser; +import org.apache.lucene.gdata.data.ServerBaseEntry; +import org.apache.lucene.gdata.server.GDataEntityBuilder; +import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.Hit; +import org.apache.lucene.search.Hits; +import org.apache.lucene.search.Searcher; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.SortField; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.BooleanClause.Occur; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; +import com.google.gdata.util.ParseException; + +/** + * StorageQuery wrapps a Lucene {@link org.apache.lucene.search.IndexSearcher} + * and a {@link org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer} to + * perform all request on the lucene storage. The wrapped components are thread - + * safe. + *

+ * An instance of this class will serve all client requests. To obtain the + * current instance of the {@link StorageQuery} the method + * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#getStorageQuery()} + * has to be invoked. This method will release the current StorageQuery. + *

+ * + * @see org.apache.lucene.search.IndexSearcher + * @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController + * @see org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer + * + * @author Simon Willnauer + * + */ +public class StorageQuery { + private final StorageBuffer buffer; + + private final Searcher searcher; + + /* + * Sort the result by timestamp desc + */ + private final Sort timeStampSort = new Sort(new SortField( + StorageEntryWrapper.FIELD_TIMESTAMP, SortField.STRING, true)); + + /** + * Creates a new StorageQuery + * + * @param buffer - + * the buffer instance to get the buffered inserts, updates from. + * @param searcher - + * the searcher instance to use to query the storage index. + * + * + */ + protected StorageQuery(final StorageBuffer buffer, final Searcher searcher) { + + this.buffer = buffer; + this.searcher = searcher; + + } + + private Hits storageQuery(List entryId) throws IOException { + BooleanQuery query = new BooleanQuery(); + /* + * query the index using a BooleanQuery + */ + for (String id : entryId) { + TermQuery termQuery = new TermQuery(new Term( + StorageEntryWrapper.FIELD_ENTRY_ID, id)); + // use an OR query + query.add(new BooleanClause(termQuery, Occur.SHOULD)); + } + + return this.searcher.search(query, new ModifiedEntryFilter(this.buffer + .getExculdList())); + } + + /* + * query the storage index for a entire feed. + */ + private Hits storageFeedQuery(final String feedId, final Sort sort) + throws IOException { + TermQuery query = new TermQuery(new Term( + StorageEntryWrapper.FIELD_FEED_REFERENCE, feedId)); + return this.searcher.search(query, new ModifiedEntryFilter(this.buffer + .getExculdList()), sort); + + } + + /* + * get a single entry + */ + private Hits storageQuery(String entryId) throws IOException { + TermQuery termQuery = new TermQuery(new Term( + StorageEntryWrapper.FIELD_ENTRY_ID, entryId)); + /* + * Filter entries inside the buffer, buffered entries might contain + * deleted entries. These entries must be found!! + */ + return this.searcher.search(termQuery, new ModifiedEntryFilter( + this.buffer.getExculdList())); + + } + + /** + * This method fetches the latest feed entries from the storage. Feed + * ususaly requested via a search query or as a simple query to the REST + * interface. + *

+ * The REST interface requestes all the entries from a Storage. The Storage + * retrieves the entries corresponding to the parameters specified. This + * method first requests the latest entries or updated entries from the + * {@link StorageBuffer}. If the buffer already contains enought entries + * for the the specified result count the entires will be returned. If not, + * the underlaying lucene index will be searcher for all documents of the + * specified feed sorted by storing timestamp desc. + *

+ *

+ * The entries will be searched in a feed context specified by the given + * feed ID + *

+ * + * + * @param feedId - + * the requested feed, this id will be used to retrieve the + * entries. + * @param resultCount - + * how many entries are requested + * @param startIndex - + * the offset of the entriy to start from. + * @param config - + * the FeedInstanceConfiguration contaning extension profile used + * to create the entriy instances + * @return - an ordered list of {@link BaseEntry} objects, or an empty list + * if no entries could be found + * @throws IOException - + * if the index could not be queries or the entries could not be + * build + * @throws ParseException - + * if an entry could not be parsed while building it from the + * Lucene Document. + */ + // TODO check input parameter + @SuppressWarnings("unchecked") + public BaseFeed getLatestFeedQuery(final String feedId, + final int resultCount, final int startIndex, + final FeedInstanceConfigurator config) throws IOException, + ParseException { + Hits feedHits = storageFeedQuery(feedId); + if(feedHits.length() == 0) + return null; + BaseFeed retVal = buildFeedFromLuceneDocument(feedHits.doc(0),config); + + List returnList = new ArrayList(resultCount); + List bufferedWrapperList = this.buffer + .getSortedEntries(feedId); + int alreadyAdded = 0; + int offset = startIndex - 1; + + if (bufferedWrapperList != null + && bufferedWrapperList.size() >= startIndex) { + + for (; alreadyAdded < resultCount; alreadyAdded++) { + if ((bufferedWrapperList.size() - offset) > 0) { + StorageEntryWrapper wrappedEntry = bufferedWrapperList + .get(offset++); + returnList + .add(new ServerBaseEntry(wrappedEntry.getEntry())); + } else + break; + } + // reset offset + offset = startIndex - 1; + if (alreadyAdded == resultCount){ + retVal.getEntries().addAll(returnList); + return retVal; + } + } else { + /* + * if the buffersize is less than the startindex the buffersize must + * be considered. Sublists would not be a repeatable read part of + * the whole list + */ + if (bufferedWrapperList != null) + offset = startIndex - 1 - bufferedWrapperList.size(); + } + + Hits hits = storageFeedQuery(feedId, this.timeStampSort); + if (hits.length() > 0) { + + for (; (offset < hits.length()) && (alreadyAdded < resultCount); offset++, alreadyAdded++) { + Document doc = hits.doc(offset); + BaseEntry entry = buildEntryFromLuceneDocument(doc, config); + returnList.add(entry); + } + + } + + retVal.getEntries().addAll(returnList); + return retVal; + } + + /** + * This method retrieves a single entry from the storage. If the + * {@link StorageBuffer} does not contain the requested entry the + * underlaying storage index will be searched. + *

+ * The Entry will be searched in a feed context specified by the given feed + * ID + *

+ * + * @param entryId - + * the entry to fetch + * @param feedId - + * the feedid eg. feed context + * @param config - + * the FeedInstanceConfiguration contaning extension profile used + * to create the entriy instances + * @return - the requested {@link BaseEntry} or null if the + * entry can not be found + * @throws IOException - + * if the index could not be queries or the entries could not be + * build + * @throws ParseException - + * if an entry could not be parsed while building it from the + * Lucene Document. + */ + public BaseEntry singleEntryQuery(final String entryId, + final String feedId, final FeedInstanceConfigurator config) + throws IOException, ParseException { + StorageEntryWrapper wrapper = this.buffer.getEntry(entryId, feedId); + + if (wrapper == null) { + Hits hits = storageQuery(entryId); + if (hits.length() <= 0) + return null; + Document doc = hits.doc(0); + + return buildEntryFromLuceneDocument(doc, config); + } + /* + * ServerBaseEntry enables the dynamic element of the entry like the + * links to be dynamic. BufferedEntries will be reused until they are + * written. + */ + return new ServerBaseEntry(wrapper.getEntry()); + + } + + /** + * Fetches the requested entries from the storage. The given list contains + * entry ids to be looked up in the storage. First the {@link StorageBuffer} + * will be queried for the entry ids. If not all of the entries remain in + * the buffer the underlaying lucene index will be searched. The entries are + * not guaranteed to be in the same order as they are in the given id list. + * Entry ID's not found in the index or the buffer will be omitted. + *

+ * The entries will be searched in a feed context specified by the given + * feed ID + *

+ * + * @param entryIds - + * the entriy ids to fetch. + * @param feedId - + * the feed id eg. feed context. + * @param config - + * the FeedInstanceConfiguration contaning extension profile used + * to create the entriy instances + * + * @return - the list of entries corresponding to the given entry id list. + * @throws IOException - + * if the index could not be queries or the entries could not be + * build + * @throws ParseException - + * if an entry could not be parsed while building it from the + * Lucene Document. + */ + public List entryQuery(List entryIds, + final String feedId, final FeedInstanceConfigurator config) + throws IOException, ParseException { + List resultList = new ArrayList(entryIds.size()); + List searchList = new ArrayList(entryIds.size()); + for (String entry : entryIds) { + + StorageEntryWrapper bufferedEntry = this.buffer.getEntry(entry, + feedId); + if (bufferedEntry != null) { + resultList.add(new ServerBaseEntry(bufferedEntry.getEntry())); + } else + searchList.add(entry); + } + if (searchList.isEmpty()) + return resultList; + + Hits hits = storageQuery(searchList); + Iterator hitIterator = hits.iterator(); + while (hitIterator.hasNext()) { + Hit hit = (Hit) hitIterator.next(); + Document doc = hit.getDocument(); + BaseEntry entry = buildEntryFromLuceneDocument(doc, config); + resultList.add(entry); + + } + + return resultList; + + } + + private BaseEntry buildEntryFromLuceneDocument(final Document doc, + final FeedInstanceConfigurator config) throws ParseException, + IOException { + StringReader reader = new StringReader(doc.getField( + StorageEntryWrapper.FIELD_CONTENT).stringValue()); + return GDataEntityBuilder.buildEntry(doc.getField( + StorageEntryWrapper.FIELD_FEED_REFERENCE).stringValue(), + reader, config); + + } + + private BaseFeed buildFeedFromLuceneDocument(final Document doc, + final FeedInstanceConfigurator config) throws ParseException, + IOException { + StringReader reader = new StringReader(doc.getField( + StorageFeedWrapper.FIELD_CONTENT).stringValue()); + return GDataEntityBuilder + .buildFeed(doc.getField(StorageFeedWrapper.FIELD_FEED_ID) + .stringValue(), reader, config); + + } + + /** + * Queries the storage for an user instance + * + * @param username - + * the username (primary key) + * @return - the user instance if found or null if not exists + * @throws IOException - + * if the storage can not be accessed. + */ + public GDataUser getUser(final String username) throws IOException { + if (username == null) + return null; + TermQuery query = new TermQuery(new Term( + StorageUserWrapper.FIELD_USERNAME, username)); + Hits h = this.searcher.search(query); + if (h.length() == 0) + return null; + return StorageUserWrapper.buildEntity(h.doc(0)); + } + + /** + * Closes all resources used in the {@link StorageQuery}. The instance can + * not be reused after invoking this method. + * + * @throws IOException - + * if the resouces can not be closed + */ + public void close() throws IOException { + this.searcher.close(); + this.buffer.close(); + } + + /** + * Checks whether a feed for the given feedID is stored + * @param feedId - the feed ID + * @return true if and only if a feed is stored for the provided feed ID, false if no feed for the given id is stored + * @throws IOException + */ + public boolean isFeedStored(String feedId)throws IOException{ + Hits h = storageFeedQuery(feedId); + return (h.length() > 0); + + } + + /** + * Looks up the feedtype for the given feed ID + * @param feedID - the feed ID + * @return - the feed type + * @throws IOException - if the storage can not be accessed + */ + public String getFeedType(String feedID) throws IOException { + Hits hits = storageFeedQuery(feedID); + if (hits.length() <= 0) + return null; + Document doc = hits.doc(0); + String feedType = doc.get(StorageFeedWrapper.FIELD_FEED_TYPE); + return feedType; + } + private Hits storageFeedQuery(String feedId) throws IOException { + TermQuery query = new TermQuery(new Term( + StorageFeedWrapper.FIELD_FEED_ID, feedId)); + return this.searcher.search(query); + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/ReferenceCounter.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/ReferenceCounter.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/ReferenceCounter.java (working copy) @@ -72,6 +72,8 @@ */ public final Type get() { return this.resource; - } + } + + } Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java (working copy) @@ -91,7 +91,8 @@ if (this.runner == null) { UIDProducer producer = new UIDProducer(this.blockingQueue, this.secureRandom, this.mdigest); - this.runner = new Thread(producer); + this.runner = new Thread(producer); + this.runner.setDaemon(true); this.runner.start(); } } Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java (working copy) @@ -16,6 +16,9 @@ package org.apache.lucene.gdata.storage; import java.util.List; + +import org.apache.lucene.gdata.data.GDataUser; +import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; import com.google.gdata.data.BaseEntry; import com.google.gdata.data.BaseFeed; @@ -30,7 +33,13 @@ * */ public interface Storage { - + /** + * Returns the type of the Feed like {@link com.google.gdata.data.Feed} wich is registered with every feed. + * @param feedID - the id of the feed + * @return - the feed type + * @throws StorageException - if no feed for the feedId is stored or the storage can not be accessed + */ + public abstract String getFeedType(String feedID)throws StorageException; /** * This stores an incoming entry for a later retrival. * The Entry will be associated with the feedid. @@ -88,9 +97,44 @@ String feedId) throws StorageException; /** - * @param profile + * @param config */ - public abstract void setExtensionProfile(final ExtensionProfile profile); + public abstract void setFeedInstanceConfig(final FeedInstanceConfigurator config); + + + /** + * @param user + * @throws StorageException + */ + public abstract void saveUser(final GDataUser user) throws StorageException; + /** + * @param user + * @throws StorageException + */ + public abstract void updateUser(final GDataUser user) throws StorageException; + /** + * @param username + * @throws StorageException + */ + public abstract void deleteUser(final String username) throws StorageException; + + /** + * @param feed + * @param username + * @throws StorageException + */ + public abstract void insertFeed(final BaseFeed feed, String username)throws StorageException; + /** + * @param feedId + * @throws StorageException + */ + public abstract void deleteFeed(final String feedId)throws StorageException; + /** + * @param feed + * @param username + * @throws StorageException + */ + public abstract void updateFeed(final BaseFeed feed, String username)throws StorageException; /** * close this storage instance Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java (working copy) @@ -1,27 +1,33 @@ -/** - * Copyright 2004 The Apache Software Foundation - * - * 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.apache.lucene.gdata.storage; - -/** - * @author Simon Willnauer - * - */ -public interface StorageController { -/** - * Destroys the controller - */ -public abstract void destroy(); -} +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.storage; + +/** + * @author Simon Willnauer + * + */ +public interface StorageController { +/** + * Destroys the controller + */ +public abstract void destroy(); + +/** + * @return a storage instance + * @throws StorageException + */ +public abstract Storage getStorage()throws StorageException; +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java (working copy) @@ -15,10 +15,8 @@ */ package org.apache.lucene.gdata.storage; -import java.io.IOException; +import org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation; -import org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation; - /** *TODO document me * @author Simon Willnauer @@ -33,7 +31,7 @@ public static Storage getStorage()throws StorageException{ try { return new StorageImplementation(); - } catch (IOException e) { + } catch (StorageException e) { StorageException ex = new StorageException("Can't create Storage instance -- " + e.getMessage(), e); ex.setStackTrace(e.getStackTrace()); Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java (working copy) @@ -39,7 +39,7 @@ * * */ -public abstract class Service { +public interface Service { /** * Service method to create an entry in an already created and existing Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java (working copy) @@ -1,275 +1,287 @@ -/** - * Copyright 2004 The Apache Software Foundation +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.server; + +import java.io.IOException; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.registry.ComponentType; +import org.apache.lucene.gdata.server.registry.GDataServerRegistry; +import org.apache.lucene.gdata.storage.Storage; +import org.apache.lucene.gdata.storage.StorageController; +import org.apache.lucene.gdata.storage.StorageException; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.DateTime; +import com.google.gdata.data.Generator; +import com.google.gdata.data.Link; +import com.google.gdata.util.ParseException; + +/** + * @author Simon Willnauer * - * 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.apache.lucene.gdata.server; + */ +public class GDataService implements Service { + private static final Log LOGGER = LogFactory.getLog(GDataService.class); + + protected Storage storage; + + protected GDataServerRegistry registry = GDataServerRegistry.getRegistry(); + + private static final Generator generator; + + private static final String generatorName = "Lucene GData-Server"; + + private static final String generatorURI = "http://lucene.apache.org"; + private static final String XMLMIME = "application/atom+xml"; + static { + generator = new Generator(); + generator.setName(generatorName); + generator.setUri(generatorURI); + generator.setVersion("0.1"); + } + + protected GDataService() throws ServiceException { + try { + StorageController controller = GDataServerRegistry.getRegistry().lookup(StorageController.class,ComponentType.STORAGECONTROLLER); + if(controller == null) + throw new StorageException("StorageController is not registered"); + this.storage = controller.getStorage(); + + } catch (StorageException e) { + LOGGER + .fatal( + "Can't get Storage Instance -- can't serve any requests", + e); + ServiceException ex = new ServiceException( + "Can't get Storage instance" + e.getMessage(), e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + } + + /** + * @see org.apache.lucene.gdata.server.Service#createEntry(org.apache.lucene.gdata.server.GDataRequest, + * org.apache.lucene.gdata.server.GDataResponse) + */ + + public BaseEntry createEntry(GDataRequest request, GDataResponse response) + throws ServiceException { + + this.storage.setFeedInstanceConfig(request.getConfigurator()); + if (LOGGER.isInfoEnabled()) + LOGGER.info("create Entry for feedId: " + request.getFeedId()); + BaseEntry entry = buildEntry(request); + setTimeStamps(entry); + try { + + this.storage.storeEntry(entry, request.getFeedId()); + } catch (Exception e) { + ServiceException ex = new ServiceException("Could not store entry", + e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + return entry; + } + + /** + * @see org.apache.lucene.gdata.server.Service#deleteEntry(org.apache.lucene.gdata.server.GDataRequest, + * org.apache.lucene.gdata.server.GDataResponse) + */ + + public BaseEntry deleteEntry(GDataRequest request, GDataResponse response) + throws ServiceException { + this.storage.setFeedInstanceConfig(request.getConfigurator()); + String entryid = request.getEntryId(); + String feedid = request.getFeedId(); + try { + this.storage.deleteEntry(entryid, feedid); + } catch (Exception e) { + ServiceException ex = new ServiceException( + "Could not delete entry", e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + return null; + } + + /** + * @see org.apache.lucene.gdata.server.Service#updateEntry(org.apache.lucene.gdata.server.GDataRequest, + * org.apache.lucene.gdata.server.GDataResponse) + */ + + public BaseEntry updateEntry(GDataRequest request, GDataResponse response) + throws ServiceException { + + this.storage.setFeedInstanceConfig(request.getConfigurator()); + BaseEntry entry = buildEntry(request); + String feedid = request.getFeedId(); + if (LOGGER.isInfoEnabled()) + LOGGER.info("update Entry" + entry.getId() + " for feedId: " + + feedid); + setTimeStamps(entry); + try { + this.storage.updateEntry(entry, feedid); + } catch (StorageException e) { + ServiceException ex = new ServiceException( + "Could not update entry", e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + return entry; + } + + /** + * @see org.apache.lucene.gdata.server.Service#getFeed(org.apache.lucene.gdata.server.GDataRequest, + * org.apache.lucene.gdata.server.GDataResponse) + */ + @SuppressWarnings("unchecked") -import java.io.IOException; -import java.util.List; + public BaseFeed getFeed(GDataRequest request, GDataResponse response) + throws ServiceException { + this.storage.setFeedInstanceConfig(request.getConfigurator()); + + try { + BaseFeed feed = this.storage.getFeed(request.getFeedId(), request + .getStartIndex(), request.getItemsPerPage()); + dynamicElementFeedStragey(feed,request); + + + + return feed; + } catch (StorageException e) { + ServiceException ex = new ServiceException("Could not get feed", e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + + } + + + private Link buildLink(String rel, String type, String href) { + Link retVal = new Link(); + retVal.setHref(href); + retVal.setRel(rel); + retVal.setType(type); + return retVal; + } + + + + private BaseEntry buildEntry(final GDataRequest request) + throws ServiceException { + try { + return GDataEntityBuilder.buildEntry(request); + + } catch (ParseException e) { + ServiceException ex = new ServiceException( + "Could not parse entry from incoming request", e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } catch (IOException e) { + ServiceException ex = new ServiceException( + "Could not read or open input stream", e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + } + + + + private BaseEntry setTimeStamps(final BaseEntry entry) { + if(entry.getUpdated() == null) + entry.setUpdated(DateTime.now()); + if(entry.getPublished() == null) + entry.setPublished(DateTime.now()); + return entry; + } + + /** + * @see org.apache.lucene.gdata.server.Service#getSingleEntry(org.apache.lucene.gdata.server.GDataRequest, + * org.apache.lucene.gdata.server.GDataResponse) + */ -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.gdata.server.registry.GDataServerRegistry; -import org.apache.lucene.gdata.storage.Storage; -import org.apache.lucene.gdata.storage.StorageException; -import org.apache.lucene.gdata.storage.StorageFactory; - -import com.google.gdata.data.BaseEntry; -import com.google.gdata.data.BaseFeed; -import com.google.gdata.data.DateTime; -import com.google.gdata.data.Generator; -import com.google.gdata.data.Link; -import com.google.gdata.util.ParseException; - -/** - * @author Simon Willnauer - * - */ -public class GDataService extends Service { - private static final Log LOGGER = LogFactory.getLog(GDataService.class); - - private Storage storage; - - private GDataServerRegistry registry = GDataServerRegistry.getRegistry(); - - private static final Generator generator; - - private static final String generatorName = "Lucene GData-Server"; - - private static final String generatorURI = "http://lucene.apache.org"; - static { - generator = new Generator(); - generator.setName(generatorName); - generator.setUri(generatorURI); - generator.setVersion("0.1"); - } - - protected GDataService() throws ServiceException { - try { - this.storage = StorageFactory.getStorage(); - - } catch (StorageException e) { - LOGGER - .fatal( - "Can't get Storage Instance -- can't serve any requests", - e); - ServiceException ex = new ServiceException( - "Can't get Storage instance" + e.getMessage(), e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - } - } - - /** - * @see org.apache.lucene.gdata.server.Service#createEntry(org.apache.lucene.gdata.server.GDataRequest, - * org.apache.lucene.gdata.server.GDataResponse) - */ - @Override - public BaseEntry createEntry(GDataRequest request, GDataResponse response) - throws ServiceException { - - checkFeedIsRegisterd(request); - if (LOGGER.isInfoEnabled()) - LOGGER.info("create Entry for feedId: " + request.getFeedId()); - BaseEntry entry = buildEntry(request); - setUpdateTime(entry); - try { - - this.storage.storeEntry(entry, request.getFeedId()); - } catch (Exception e) { - ServiceException ex = new ServiceException("Could not store entry", - e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - } - return entry; - } - - /** - * @see org.apache.lucene.gdata.server.Service#deleteEntry(org.apache.lucene.gdata.server.GDataRequest, - * org.apache.lucene.gdata.server.GDataResponse) - */ - @Override - public BaseEntry deleteEntry(GDataRequest request, GDataResponse response) - throws ServiceException { - checkFeedIsRegisterd(request); - String entryid = request.getEntryId(); - String feedid = request.getFeedId(); - try { - this.storage.deleteEntry(entryid, feedid); - } catch (Exception e) { - ServiceException ex = new ServiceException( - "Could not delete entry", e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - } - return null; - } - - /** - * @see org.apache.lucene.gdata.server.Service#updateEntry(org.apache.lucene.gdata.server.GDataRequest, - * org.apache.lucene.gdata.server.GDataResponse) - */ - @Override - public BaseEntry updateEntry(GDataRequest request, GDataResponse response) - throws ServiceException { - checkFeedIsRegisterd(request); - - BaseEntry entry = buildEntry(request); - String feedid = request.getFeedId(); - if (LOGGER.isInfoEnabled()) - LOGGER.info("update Entry" + entry.getId() + " for feedId: " - + feedid); - setUpdateTime(entry); - try { - this.storage.updateEntry(entry, feedid); - } catch (StorageException e) { - ServiceException ex = new ServiceException( - "Could not update entry", e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - } - return entry; - } - - /** - * @see org.apache.lucene.gdata.server.Service#getFeed(org.apache.lucene.gdata.server.GDataRequest, - * org.apache.lucene.gdata.server.GDataResponse) - */ - @SuppressWarnings("unchecked") - @Override - public BaseFeed getFeed(GDataRequest request, GDataResponse response) - throws ServiceException { - checkFeedIsRegisterd(request); - - try { - // TODO remove when storing feeds is implemented just for - // development - BaseFeed feed = this.storage.getFeed(request.getFeedId(), request - .getStartIndex(), request.getItemsPerPage()); - buildDynamicFeedElements(request, feed); - List list = feed.getEntries(); - addContextPath(list, request.getContextPath()); - return feed; - } catch (StorageException e) { - ServiceException ex = new ServiceException("Could not get feed", e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - } - - } - - /* - * build the dynamic elements like self link and next link - */ - private void buildDynamicFeedElements(final GDataRequest request, - final BaseFeed feed) { - feed.setGenerator(generator); - feed.setItemsPerPage(request.getItemsPerPage()); - feed.getLinks().add( - buildLink(Link.Rel.SELF, Link.Type.ATOM, request.getSelfId())); - // TODO add next link - } - - private Link buildLink(String rel, String type, String href) { - Link retVal = new Link(); - retVal.setHref(href); - retVal.setRel(rel); - retVal.setType(type); - return retVal; - } - - /* - * every entry has an ID which has to have a prefix. The prefix is the - * context path of the requested feed. This will be used to request the - * entry directly - */ - private void addContextPath(List list, final String contextPath) { - for (BaseEntry entry : list) { - addcontextPath(entry, contextPath); - } - } - - @SuppressWarnings("unchecked") - private BaseEntry addcontextPath(final BaseEntry entry, - final String contextPath) { - String id = contextPath + entry.getId(); - entry.setId(id); - Link self = new Link(); - self.setRel("self"); - self.setHref(id); - self.setType("application/atom+xml"); - entry.getLinks().add(self); - return entry; - } - - private BaseEntry buildEntry(final GDataRequest request) - throws ServiceException { - try { - return GDataEntityBuilder.buildEntry(request); - - } catch (ParseException e) { - ServiceException ex = new ServiceException( - "Could not parse entry from incoming request", e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - } catch (IOException e) { - ServiceException ex = new ServiceException( - "Could not read or open input stream", e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - } - } - - /* - * checks whether the reqeuested feed is registered - */ - private void checkFeedIsRegisterd(final GDataRequest request) - throws FeedNotFoundException { - if (!this.registry.isFeedRegistered(request.getFeedId())) - throw new FeedNotFoundException( - "Feed could not be found - is not registed - Feed ID:" - + request.getFeedId()); - this.storage.setExtensionProfile(request.getExtensionProfile()); - } - - private BaseEntry setUpdateTime(final BaseEntry entry) { - entry.setUpdated(DateTime.now()); - return entry; - } - - /** - * @see org.apache.lucene.gdata.server.Service#getSingleEntry(org.apache.lucene.gdata.server.GDataRequest, - * org.apache.lucene.gdata.server.GDataResponse) - */ - @Override - public BaseEntry getSingleEntry(GDataRequest request, GDataResponse response) - throws ServiceException { - checkFeedIsRegisterd(request); - - try { - BaseEntry entry = this.storage.getEntry(request.getEntryId(), - request.getFeedId()); - if(entry == null) - return null; - addcontextPath(entry, request.getContextPath()); - return entry; - } catch (StorageException e) { - ServiceException ex = new ServiceException("Could not get feed", e); - ex.setStackTrace(e.getStackTrace()); - throw ex; - } - } - -} + public BaseEntry getSingleEntry(GDataRequest request, GDataResponse response) + throws ServiceException { + this.storage.setFeedInstanceConfig(request.getConfigurator()); + + try { + BaseEntry entry = this.storage.getEntry(request.getEntryId(), + request.getFeedId()); + if(entry == null) + return null; + dynamicElementEntryStragey(entry,request); + + return entry; + } catch (StorageException e) { + ServiceException ex = new ServiceException("Could not get feed", e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + } + + + /* + * adds all dynamic element to the entry + */ + private void dynamicElementEntryStragey(final BaseEntry entry, final GDataRequest request){ + setSelfLink(entry,request.getContextPath()); + } + /* + * adds all dynamic element to the feed entries + */ + @SuppressWarnings("unchecked") + private void dynamicElementFeedStragey(final BaseFeed feed, final GDataRequest request){ + buildDynamicFeedElements(request,feed); + List entryList = feed.getEntries(); + for (BaseEntry entry : entryList) { + String id = request.getContextPath() + entry.getId(); + setSelfLink(entry,id); + } + + } + /* + * every entry has an ID which has to have a prefix. The prefix is the + * context path of the requested feed. This will be used to request the + * entry directly + */@SuppressWarnings("unchecked") + private BaseEntry setSelfLink(final BaseEntry entry, + String id) { + + entry.setId(id); + Link self = buildLink(Link.Rel.SELF,XMLMIME,id); + entry.getLinks().add(self); + return entry; + } + /* + * build the dynamic elements like self link and next link + */ + private void buildDynamicFeedElements(final GDataRequest request, + final BaseFeed feed) { + feed.setGenerator(generator); + feed.setItemsPerPage(request.getItemsPerPage()); + feed.getLinks().add( + buildLink(Link.Rel.SELF, Link.Type.ATOM, request.getSelfId())); + feed.getLinks().add(buildLink(Link.Rel.NEXT,XMLMIME,request.getNextId())); + + } + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java (working copy) @@ -15,18 +15,17 @@ */ package org.apache.lucene.gdata.server; -import java.io.IOException; -import java.io.Reader; +import java.io.IOException; +import java.io.Reader; + +import org.apache.lucene.gdata.server.registry.DataBuilderException; +import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.util.ParseException; -import org.apache.lucene.gdata.server.registry.DataBuilderException; -import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; -import org.apache.lucene.gdata.server.registry.GDataServerRegistry; - -import com.google.gdata.data.BaseEntry; -import com.google.gdata.data.BaseFeed; -import com.google.gdata.data.ExtensionProfile; -import com.google.gdata.util.ParseException; - /** * {@link com.google.gdata.data.BaseFeed}, * {@link com.google.gdata.data.BaseEntry} instances have to be build from a @@ -44,7 +43,7 @@ * */ public class GDataEntityBuilder { - private static final GDataServerRegistry REGISTRY = GDataServerRegistry.getRegistry(); // TODO find another way for getting the registered feeds + /** * Builds a {@link BaseFeed} instance from the {@link Reader} provided by @@ -53,18 +52,18 @@ * @param request - * the request to build the instance from * @return - a BaseFeed instance - * @throws FeedNotFoundException - - * if the feed is not registered + * @throws IOException - * if an I/O Exception occures on the provided reader * @throws ParseException - * if the feed could not be parsed */ public static BaseFeed buildFeed(final GDataRequest request) - throws FeedNotFoundException, IOException, ParseException { + throws IOException, ParseException { if (request == null) - throw new IllegalArgumentException("request must not be null"); - return buildFeed(request.getFeedId(), request.getReader(),request.getExtensionProfile()); + throw new IllegalArgumentException("request must not be null"); + FeedInstanceConfigurator config = request.getConfigurator(); + return buildFeed(request.getFeedId(), request.getReader(),config); } /** @@ -74,30 +73,28 @@ * the feed ID to request the feed type from the registry * @param reader - * the reader to build the feed from - * @param profile - extension profile to parse the resource + * @param config - the feed instance config containing the extension profile to parse the resource * @return - a BaseFeed instance - * @throws FeedNotFoundException - - * if the feed is not registered + * @throws IOException - * if an I/O Exception occures on the provided reader * @throws ParseException - * if the feed could not be parsed */ - public static BaseFeed buildFeed(final String feedId, final Reader reader,final ExtensionProfile profile) - throws FeedNotFoundException, ParseException, IOException { + public static BaseFeed buildFeed(final String feedId, final Reader reader,final FeedInstanceConfigurator config) + throws ParseException, IOException { BaseFeed retVal = null; try { - retVal = (BaseFeed) createEntityInstance(feedId); - } catch (FeedNotFoundException e) { - throw e; + retVal = (BaseFeed) createEntityInstance(config); + } catch (Exception e) { DataBuilderException ex = new DataBuilderException( "Could not build Feed for Feed class ", e); ex.setStackTrace(e.getStackTrace()); throw ex; } - retVal.parseAtom(profile, reader); + retVal.parseAtom(config.getExtensionProfilClass(), reader); return retVal; } @@ -109,18 +106,18 @@ * @param request - * the request to build the instance from * @return - a BaseEntry instance - * @throws FeedNotFoundException - - * if the feed, requested by the client is not registered + * * @throws IOException - * if an I/O Exception occures on the provided reader * @throws ParseException - * if the entry could not be parsed */ public static BaseEntry buildEntry(final GDataRequest request) - throws FeedNotFoundException, IOException, ParseException { + throws IOException, ParseException { if (request == null) throw new IllegalArgumentException("request must not be null"); - return buildEntry(request.getFeedId(), request.getReader(),request.getExtensionProfile()); + FeedInstanceConfigurator config = request.getConfigurator(); + return buildEntry(request.getFeedId(), request.getReader(),config); } /** @@ -130,23 +127,21 @@ * the feed ID to request the feed type from the registry * @param reader - * the reader to build the feed from - * @param profile - extension profile to parse the resource + * @param config - the instance config containing the extension profile to parse the resource * @return - a BaseFeed instance - * @throws FeedNotFoundException - - * if the feed is not registered + * * @throws IOException - * if an I/O Exception occures on the provided reader * @throws ParseException - * if the entry could not be parsed */ - public static BaseEntry buildEntry(final String feedId, final Reader reader,final ExtensionProfile profile) - throws FeedNotFoundException, ParseException, IOException { + public static BaseEntry buildEntry(final String feedId, final Reader reader,final FeedInstanceConfigurator config) + throws ParseException, IOException { BaseEntry retVal = null; try { - retVal = ((BaseFeed) createEntityInstance(feedId)).createEntry(); - } catch (FeedNotFoundException e) { - throw e; + retVal = ((BaseFeed) createEntityInstance(config)).createEntry(); + } catch (Exception e) { DataBuilderException ex = new DataBuilderException( "Could not build Entry for Entry class ", e); @@ -157,15 +152,10 @@ return retVal; } - private static Object createEntityInstance(String feedId) - throws FeedNotFoundException, InstantiationException, + private static Object createEntityInstance(final FeedInstanceConfigurator config) + throws InstantiationException, IllegalAccessException { - FeedInstanceConfigurator config = REGISTRY.getFeedConfigurator(feedId); - if (config == null) - throw new FeedNotFoundException( - "No feed for requested feed ID found - " + feedId); - Class feedClass = config.getFeedType(); - return feedClass.newInstance(); + return config.getFeedType().newInstance(); } } Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/administration/AdminService.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/administration/AdminService.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/administration/AdminService.java (revision 0) @@ -0,0 +1,108 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.server.administration; + +import org.apache.lucene.gdata.data.GDataUser; +import org.apache.lucene.gdata.server.Service; +import org.apache.lucene.gdata.server.ServiceException; + +import com.google.gdata.data.BaseFeed; + +/** + * The AdminService interface extends the Service interface to serve common + * administrator requests. Common users can not create feed or user instances. + * This interface provides all actions for create, delete or update Users and + * Feeds. Each Feed has an associated Feed - Name which acts as an ID. Feed will + * be identified by the feed name e.g. {@link com.google.gdata.data.Source#getId()} + *

User accounts are supposed to have a unique username attribute as the username acts as a primary key for the storage

+ * + * + * @author Simon Willnauer + * + */ +public interface AdminService extends Service { + + /** + * Creates a new feed instance. + * + * @param feed - + * the feed to create + * @param username - + * the username this feed belongs to + * @throws ServiceException - + * if the feed can not be created + */ + public abstract void createFeed(final BaseFeed feed, + final String username) throws ServiceException; + + /** + * Updates the given feed + * + * @param feed - + * the feed to update + * @param username - + * the username this feed belongs to + * @throws ServiceException - + * if the feed can not be updated or does not exist. + */ + public abstract void updateFeed(final BaseFeed feed, + final String username) throws ServiceException; + + /** + * Deletes the given feed from the storage. The feed will not be accessable + * anymore. + * + * @param feed - + * the feed to deltete + * + * @throws ServiceException - + * if the feed can not be deleted or does not exist + */ + public abstract void deleteFeed(final BaseFeed feed) throws ServiceException; + + /** + * Creates a new User accout. + * + * @param user - + * the user to create + * @throws ServiceException - + * if the user can not be created or the user does already + * exist. + */ + public abstract void createUser(final GDataUser user) + throws ServiceException; + + /** + * Deletes the given user from the storage. it will also delete all + * accociated feeds. + * + * @param user + * the user to delete + * @throws ServiceException - + * if the user does not exist or the user can not be deleted + */ + public abstract void deleteUser(final GDataUser user) + throws ServiceException; + + /** + * Updates the given user if the user already exists. + * + * @param user - the user to update + * @throws ServiceException - if the user can not be updated or the user does not exist + */ + public abstract void updateUser(final GDataUser user) + throws ServiceException; +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/administration/GDataAdminService.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/administration/GDataAdminService.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/administration/GDataAdminService.java (revision 0) @@ -0,0 +1,115 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.server.administration; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.data.GDataUser; +import org.apache.lucene.gdata.server.GDataService; +import org.apache.lucene.gdata.server.ServiceException; +import org.apache.lucene.gdata.storage.StorageException; + +import com.google.gdata.data.BaseFeed; + + + +/** + * @author Simon Willnauer + * + */ +public class GDataAdminService extends GDataService implements AdminService { + private static final Log LOG = LogFactory.getLog(GDataAdminService.class); + protected GDataAdminService() throws ServiceException { + super(); + + } + + + /** + * @see org.apache.lucene.gdata.server.administration.AdminService#createFeed(com.google.gdata.data.BaseFeed, java.lang.String) + */ + public void createFeed(BaseFeed feed, String username) throws ServiceException { + if(feed == null) + throw new ServiceException("Can not create null feed"); + + } + + + /** + * @see org.apache.lucene.gdata.server.administration.AdminService#updateFeed(com.google.gdata.data.BaseFeed, java.lang.String) + */ + public void updateFeed(BaseFeed feed, String username) throws ServiceException { + if(feed == null) + throw new ServiceException("Can not update null feed"); + } + + + /** + * @see org.apache.lucene.gdata.server.administration.AdminService#deleteFeed(com.google.gdata.data.BaseFeed) + */ + public void deleteFeed(BaseFeed feed) throws ServiceException { + if(feed == null) + throw new ServiceException("Can not delete null feed"); + } + + /** + * @see org.apache.lucene.gdata.server.administration.AdminService#createUser(org.apache.lucene.gdata.data.GDataUser) + */ + public void createUser(GDataUser user) throws ServiceException { + if(user == null) + throw new ServiceException("Can not save null user"); + try { + this.storage.saveUser(user); + } catch (StorageException e) { + if(LOG.isInfoEnabled()) + LOG.info("Can not save User -- "+e.getMessage(),e); + throw new ServiceException("Can not save user",e); + } + } + + /** + * @see org.apache.lucene.gdata.server.administration.AdminService#deleteUser(org.apache.lucene.gdata.data.GDataUser) + */ + public void deleteUser(GDataUser user) throws ServiceException { + if(user == null) + throw new ServiceException("Can not delete null user"); + try { + this.storage.deleteUser(user.getUsername()); + } catch (StorageException e) { + if(LOG.isInfoEnabled()) + LOG.info("Can not save User -- "+e.getMessage(),e); + throw new ServiceException("Can not save user",e); + } + } + + /** + * @see org.apache.lucene.gdata.server.administration.AdminService#updateUser(org.apache.lucene.gdata.data.GDataUser) + */ + public void updateUser(GDataUser user) throws ServiceException { + if(user == null) + throw new ServiceException("Can not update null user"); + try { + this.storage.updateUser(user); + } catch (StorageException e) { + if(LOG.isInfoEnabled()) + LOG.info("Can not save User -- "+e.getMessage(),e); + throw new ServiceException("Can not save user",e); + } + } + + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java (working copy) @@ -1,57 +1,60 @@ -/** - * Copyright 2004 The Apache Software Foundation - * - * 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.apache.lucene.gdata.server; - - -/** - * The {@link ServiceFactory} creates {@link Service} implementations to access - * the GData - Server components. - * - * @author Simon Willnauer - * - */ -public class ServiceFactory { - - private static ServiceFactory INSTANCE = null; - - /** - * @return - a Singleton Instance of the factory - */ - public static synchronized ServiceFactory getInstance() { - if (INSTANCE == null) - INSTANCE = new ServiceFactory(); - return INSTANCE; - - } - - private ServiceFactory() { - // private constructor --> singleton - } - - /** - * Creates a {@link Service} implementation. - * - * @return a Service Implementation - */ - public Service getService() { - try{ - return new GDataService(); - }catch (Exception e) { - // - } - return null; - } -} +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.server; + +import org.apache.lucene.gdata.server.registry.Component; +import org.apache.lucene.gdata.server.registry.ComponentType; + + +/** + * The {@link ServiceFactory} creates {@link Service} implementations to access + * the GData - Server components. + * This class should not be access directy. The class will be registered in the {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry}. + * Use {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry#lookup(Class, ComponentType)} + * + * @author Simon Willnauer + * + */ +@Component(componentType=ComponentType.SERVICEFACTORY) +public class ServiceFactory { + + + + + + /** + * public constructor to enable loading via the registry + * @see org.apache.lucene.gdata.server.registry.Component + * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry + */ + public ServiceFactory() { + // + } + + /** + * Creates a {@link Service} implementation. + * + * @return a Service Implementation + */ + public Service getService() { + try{ + return new GDataService(); + }catch (Exception e) { + // + } + return null; + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java (working copy) @@ -12,30 +12,73 @@ * 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.lucene.gdata.server.registry; - -import com.google.gdata.data.ExtensionProfile; -import com.google.gdata.data.Feed; - -/** - * @author Simon Willnauer + */ +package org.apache.lucene.gdata.server.registry; + +import org.apache.lucene.gdata.storage.Storage; +import org.apache.lucene.gdata.storage.StorageController; +import org.apache.lucene.gdata.storage.StorageException; +import org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController; + +import com.google.gdata.data.DateTime; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.data.Feed; +import com.google.gdata.data.Person; +import com.google.gdata.data.PlainTextConstruct; +import com.google.gdata.data.extensions.EventFeed; + +/** + * @author Simon Willnauer * - */ -public class RegistryBuilder { - - /** - * - */ - public static void buildRegistry(){ - // TODO Implement this!! -- just for develping purposes - GDataServerRegistry reg = GDataServerRegistry.getRegistry(); - FeedInstanceConfigurator configurator = new FeedInstanceConfigurator(); - configurator.setFeedType(Feed.class); - configurator.setFeedId("weblog"); - configurator.setExtensionProfileClass(ExtensionProfile.class); - reg.registerFeed(configurator); - - } - -} + */ +public class RegistryBuilder { + + /** + * @throws RegistryException + * + */ + public static void buildRegistry() { + // TODO Implement this!! -- just for develping purposes + GDataServerRegistry reg = GDataServerRegistry.getRegistry(); + FeedInstanceConfigurator configurator = new FeedInstanceConfigurator(); + configurator.setFeedType(Feed.class); + configurator.setExtensionProfile(new ExtensionProfile()); + reg.registerFeed(configurator); + FeedInstanceConfigurator configuratorEntryFeed = new FeedInstanceConfigurator(); + configuratorEntryFeed.setFeedType(EventFeed.class); + configuratorEntryFeed.setExtensionProfile(new ExtensionProfile()); + reg.registerFeed(configuratorEntryFeed); + + + + } + + public static void saveFeed(){ + Storage s; + + try { + GDataServerRegistry reg = GDataServerRegistry.getRegistry(); + s = reg.lookup(StorageController.class,ComponentType.STORAGECONTROLLER).getStorage(); + s.setFeedInstanceConfig(reg.getFeedConfigurator(Feed.class.getName())); + try{ + s.getFeedType("weblog"); + }catch (StorageException e) { + Feed feed = new Feed(); + feed.setTitle(new PlainTextConstruct("Simons Weblog")); + feed.setId("weblog"); + feed.getAuthors().add( + new Person("Simon Willnauer", "http://www.javawithchopsticks.de", "simon.willnauer@gmail.com")); + feed.setUpdated(DateTime.now()); + + s.insertFeed(feed, "simon"); + + } + + s.close(); + } catch (StorageException e) { + + e.printStackTrace(); + } + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/GDataServerRegistry.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/GDataServerRegistry.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/GDataServerRegistry.java (working copy) @@ -1,154 +1,226 @@ -/** - * Copyright 2004 The Apache Software Foundation - * - * 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.apache.lucene.gdata.server.registry; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.gdata.storage.StorageController; - -import com.google.gdata.data.ExtensionProfile; - -/** - * - * The FeedRegistry represents the registry component of the GData Server. All - * feed configurations will be registered here. Feed configurations contain - * several informationsa about GData feed like: - *
    - *
  1. the feed id - where the feed can be accessed via http methodes
  2. - *
  3. the feed type - feed types are implementations of the abstract - * {@link com.google.gdata.data.BaseFeed}
  4. - *
- * The registry will be set up at start up of the server application and can be - * accessed from other components to get configurations according to incoming - * requests. - * - * @author Simon Willnauer - * - */ -public class GDataServerRegistry { - private static GDataServerRegistry INSTANCE; - - private StorageController storageInstance; - - private static final Log LOGGER = LogFactory - .getLog(GDataServerRegistry.class); - - private final Map feedTypMap = new HashMap(); - - private GDataServerRegistry() { - // private - singleton - } - - /** - * @return a Sinleton registry instance - */ - public static synchronized GDataServerRegistry getRegistry() { - if (INSTANCE == null) - INSTANCE = new GDataServerRegistry(); - return INSTANCE; - } - - /** - * Registers a {@link FeedInstanceConfigurator} - * - * @param configurator - - * the configurator to register in the registry - */ - public void registerFeed(FeedInstanceConfigurator configurator) { - if (configurator == null) { - LOGGER.warn("Feedconfigurator is null -- skip registration"); - return; - } - this.feedTypMap.put(configurator.getFeedId(), configurator); - } - - /** - * Looks up the {@link FeedInstanceConfigurator} by the given feed id. - * - * @param feedId - * @return - the {@link FeedInstanceConfigurator} or null if - * the no configuration for this feed has been registered - */ - public FeedInstanceConfigurator getFeedConfigurator(String feedId) { - if (feedId == null) - throw new IllegalArgumentException( - "Feed URL is null - must not be null to get registered feedtype"); - return this.feedTypMap.get(feedId); - } - - protected void flushRegistry() { - this.feedTypMap.clear(); - } - - /** - * @param feedId - - * the id of the feed as the feed is registered - * @return - true if and only if the feed is registered, - * otherwise false. - */ - public boolean isFeedRegistered(String feedId) { - return this.feedTypMap.containsKey(feedId); - - } - - /** - * @param storage - */ - public void registerStorage(StorageController storage) { - if (this.storageInstance != null) - throw new IllegalStateException( - "Storage already registered -- Instance of " - + this.storageInstance.getClass()); - this.storageInstance = storage; - } - - /** - * Destroys the registry and release all resources - */ - public void destroy() { - flushRegistry(); - this.storageInstance.destroy(); - this.storageInstance = null; - - } - - /** - * Creates the {@link ExtensionProfile} for a registered feed - * @param feedId - the feed id - * @return - the extension profil for this feed of null if - * the feed is not registered or the extension profile could not be - * instanciated - */ - public ExtensionProfile getExtensionProfile(final String feedId) { - FeedInstanceConfigurator configurator = this.feedTypMap.get(feedId); - if (configurator == null) - return null; - Class clazz = configurator.getExtensionProfilClass(); - try { - return (ExtensionProfile) clazz.newInstance(); - } catch (Exception e) { - LOGGER - .error("Can not create instance of ExtensionProfil for class: " - + clazz + " -- feedId: " + feedId); - - } - return null; - } - -} +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.server.registry; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.storage.Storage; +import org.apache.lucene.gdata.storage.StorageController; +import org.apache.lucene.gdata.storage.StorageException; + +import com.google.gdata.data.ExtensionProfile; + +/** + * + * The FeedRegistry represents the registry component of the GData Server. All + * feed configurations will be registered here. Feed configurations contain + * several informationsa about GData feed like: + *
    + *
  1. the feed id - where the feed can be accessed via http methodes
  2. + *
  3. the feed type - feed types are implementations of the abstract + * {@link com.google.gdata.data.BaseFeed}
  4. + *
+ * The registry will be set up at start up of the server application and can be + * accessed from other components to get configurations according to incoming + * requests. + * + * @author Simon Willnauer + * + */ +public class GDataServerRegistry { + private static GDataServerRegistry INSTANCE; + + private static final Log LOGGER = LogFactory + .getLog(GDataServerRegistry.class); + //TODO replace this with a LRU HASH MAP + private final Map feedTypMap = new HashMap(); + + private final Map componentMap = new HashMap( + 10); + + private GDataServerRegistry() { + // private - singleton + } + + /** + * @return a Sinleton registry instance + */ + public static synchronized GDataServerRegistry getRegistry() { + if (INSTANCE == null) + INSTANCE = new GDataServerRegistry(); + return INSTANCE; + } + + /** + * Registers a {@link FeedInstanceConfigurator} + * + * @param configurator - + * the configurator to register in the registry + */ + public void registerFeed(FeedInstanceConfigurator configurator) { + if (configurator == null) { + LOGGER.warn("Feedconfigurator is null -- skip registration"); + return; + } + this.feedTypMap.put(configurator.getFeedType().getName(), configurator); + } + + /** + * Looks up the {@link FeedInstanceConfigurator} by the given feed id. + * + * @param feedType + * @return - the {@link FeedInstanceConfigurator} or null if + * the no configuration for this feed has been registered + */ + public FeedInstanceConfigurator getFeedConfigurator(String feedType) { + if (feedType == null) + throw new IllegalArgumentException( + "Feed Type is null - must not be null to get registered feedtype"); + return this.feedTypMap.get(feedType); + } + + + protected void flushRegistry() { + this.feedTypMap.clear(); + this.componentMap.clear(); + } + + /** + * @param feedType - the type of the feed as the feed is registered + * @return - true if and only if the feed is registered, + * otherwise false. + */ + public boolean isFeedRegistered(String feedType) { + return this.feedTypMap.containsKey(feedType); + + } + + + + /** + * Destroys the registry and release all resources + */ + public void destroy() { + ComponentBean bean = this.componentMap.get(ComponentType.STORAGECONTROLLER); + ((StorageController)bean.getObject()).destroy(); + flushRegistry(); + + + + } + + + + /** + * This method is the main interface to the Component Lookup Service of the registry. + * Every GDATA - Server component like STORAGE or the INDEXER component will be accessible via this method. + * To get a Component from the lookup service specify the expected Class as an argument and the component type of the component to return. + * For a lookup of the STORAGECONTORLER the code looks like: + *

+ * registryInstance.lookup(StorageController.class,ComponentType.STORAGECONTROLLER); + *

+ * @param the type of the expected return value + * @param clazz - Class object of the expected return value + * @param compType - The component type + * @return the registered component or null if the component can not looked up. + */ + @SuppressWarnings("unchecked") + public R lookup(Class clazz, ComponentType compType) { + ComponentBean bean = this.componentMap.get(compType); + if(bean == null) + return null; + if (bean.getSuperType().equals(clazz)) + return (R) bean.getObject(); + return null; + } + + /** + * @param componentClass + * @throws RegistryException + */ + @SuppressWarnings("unchecked") + public void registerComponent(final Class componentClass) + throws RegistryException { + + if (componentClass == null) + throw new IllegalArgumentException( + "component class must not be null"); + try { + + Component annotation = (Component) componentClass + .getAnnotation(Component.class); + if (annotation == null) + throw new RegistryException( + "can not register component. the given class is not a component -- " + + componentClass.getName()); + ComponentType type = annotation.componentType(); + if (this.componentMap.containsKey(type)) + throw new RegistryException("component already registered -- " + + type.name()); + Class superType = type.getClass().getField(type.name()).getAnnotation(SuperType.class).superType(); + if (!checkSuperType(componentClass, superType)) + throw new RegistryException("Considered Supertype <" + + superType.getName() + "> is not a super type of <" + + componentClass + ">"); + Object o = componentClass.newInstance(); + ComponentBean bean = new ComponentBean(o, superType); + this.componentMap.put(type, bean); + + } catch (Exception e) { + throw new RegistryException("Can not register component -- " + + e.getMessage(), e); + } + + } + + private static boolean checkSuperType(Class type, Class consideredSuperType) { + + if (type.equals(Object.class)) + return false; + if (type.equals(consideredSuperType)) + return true; + Class[] interfaces = type.getInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + if (interfaces[i].equals(consideredSuperType)) + return true; + } + return checkSuperType(type.getSuperclass(), consideredSuperType); + } + + private class ComponentBean { + private final Class superType; + + private final Object object; + + ComponentBean(final Object object, final Class superType) { + this.superType = superType; + this.object = object; + } + + Object getObject() { + return this.object; + } + + Class getSuperType() { + return this.superType; + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/SuperType.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/SuperType.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/SuperType.java (revision 0) @@ -0,0 +1,38 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.server.registry; + + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * @author Simon Willnauer + * + */ +@Target( { FIELD }) +@Retention(value = RUNTIME) +public @interface SuperType { + /** + * + * @return the specified super type + */ + Class superType(); +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/Component.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/Component.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/Component.java (revision 0) @@ -0,0 +1,39 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.server.registry; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * @author Simon Willnauer + * + */ +@Target( { TYPE }) +@Retention(value = RUNTIME) +public @interface Component { + + /** + * @see ComponentType + * @return - the component type + */ + ComponentType componentType(); + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryContextListener.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryContextListener.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryContextListener.java (working copy) @@ -1,65 +1,78 @@ -/** - * Copyright 2004 The Apache Software Foundation +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.server.registry; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.ServiceFactory; +import org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory; +import org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController; + +/** + * This Listener creates the + * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} when the + * context is loaded. The registry will be loaded before the + * {@link org.apache.lucene.gdata.servlet.RequestControllerServlet} is loaded. + * The Registry will be loaded and set up befor the REST interface is available. + *

+ * This ContextListener has to be configured in the web.xml + * deployment descriptor.

* - * 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 + * @author Simon Willnauer * - * 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.lucene.gdata.server.registry; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This Listener creates the - * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} when the - * context is loaded. The registry will be loaded before the - * {@link org.apache.lucene.gdata.servlet.RequestControllerServlet} is loaded. - * The Registry will be loaded and set up befor the REST interface is available. - *

- * This ContextListener has to be configured in the web.xml - * deployment descriptor.

- * - * - * @author Simon Willnauer - * - */ -public class RegistryContextListener implements ServletContextListener { - private GDataServerRegistry serverRegistry; - - private static final Log LOG = LogFactory - .getLog(RegistryContextListener.class); - - - - /** - * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) - */ - public void contextInitialized(ServletContextEvent arg0) { - LOG.info("RegistryContextListener has been loaded"); - RegistryBuilder.buildRegistry(); - this.serverRegistry = GDataServerRegistry.getRegistry(); - } - - /** - * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) - */ - public void contextDestroyed(ServletContextEvent arg0) { - LOG.info("Destroying context"); - this.serverRegistry.destroy(); - - } - -} + */ +public class RegistryContextListener implements ServletContextListener { + private GDataServerRegistry serverRegistry; + + private static final Log LOG = LogFactory + .getLog(RegistryContextListener.class); + + + + /** + * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) + */ + public void contextInitialized(ServletContextEvent arg0) { + LOG.info("RegistryContextListener has been loaded"); + RegistryBuilder.buildRegistry(); + this.serverRegistry = GDataServerRegistry.getRegistry(); + try{ + this.serverRegistry.registerComponent(ServiceFactory.class); + this.serverRegistry.registerComponent(StorageCoreController.class); + this.serverRegistry.registerComponent(DefaultRequestHandlerFactory.class); + }catch (RegistryException e) { + LOG.error("can not register requiered components",e); + } + RegistryBuilder.saveFeed(); + + + } + + /** + * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) + */ + public void contextDestroyed(ServletContextEvent arg0) { + LOG.info("Destroying context"); + this.serverRegistry.destroy(); + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/ComponentType.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/ComponentType.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/ComponentType.java (revision 0) @@ -0,0 +1,38 @@ +package org.apache.lucene.gdata.server.registry; + +import org.apache.lucene.gdata.server.ServiceFactory; +import org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory; +import org.apache.lucene.gdata.storage.StorageController; + +/** + * @author Simon Willnauer + * + */ +public enum ComponentType { + /** + * StorageController Type + * @see StorageController + */ + @SuperType(superType=StorageController.class) + STORAGECONTROLLER, + /** + * RequestHandlerFactory Type + * @see RequestHandlerFactory + */ + @SuperType(superType=RequestHandlerFactory.class) + REQUESTHANDLERFACTORY, + /** + * INDEXER TYPE + * + */ + //TODO not available yet + @SuperType(superType=Object.class) + INDEXER, + /** + * ServiceFactory Type + * @see ServiceFactory + */ + @SuperType(superType=ServiceFactory.class) + SERVICEFACTORY + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryException.java (revision 0) @@ -0,0 +1,47 @@ +package org.apache.lucene.gdata.server.registry; + +/** + * @author Simon Willnauer + * + */ +public class RegistryException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -3563720639871194466L; + + /** + * + */ + public RegistryException() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @param arg0 + */ + public RegistryException(String arg0) { + super(arg0); + // TODO Auto-generated constructor stub + } + + /** + * @param arg0 + * @param arg1 + */ + public RegistryException(String arg0, Throwable arg1) { + super(arg0, arg1); + // TODO Auto-generated constructor stub + } + + /** + * @param arg0 + */ + public RegistryException(Throwable arg0) { + super(arg0); + // TODO Auto-generated constructor stub + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java (working copy) @@ -14,6 +14,8 @@ * limitations under the License. */ package org.apache.lucene.gdata.server.registry; + +import com.google.gdata.data.ExtensionProfile; /** * @author Simon Willnauer @@ -21,8 +23,8 @@ */ public class FeedInstanceConfigurator { private Class feedType; - private String feedId; - private Class extensionProfileClass; + + private ExtensionProfile extensionProfileClass; /** * @return Returns the feedType. */ @@ -35,31 +37,20 @@ public void setFeedType(Class feedType) { this.feedType = feedType; } - /** - * @return Returns the feedURL. - */ - public String getFeedId() { - return this.feedId; - } - /** - * @param feedURL The feedURL to set. - */ - public void setFeedId(String feedURL) { - this.feedId = feedURL; - } + /** * @return - the extension profile for this feed */ - public Class getExtensionProfilClass(){ + public ExtensionProfile getExtensionProfilClass(){ return this.extensionProfileClass; } /** - * @param extensionProfilClass + * @param extensionProfil - the extensionprofile for this feed configuration */ - public void setExtensionProfileClass(Class extensionProfilClass){ - this.extensionProfileClass = extensionProfilClass; + public void setExtensionProfile(ExtensionProfile extensionProfil){ + this.extensionProfileClass = extensionProfil; } Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequest.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequest.java (revision 413530) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequest.java (working copy) @@ -16,20 +16,22 @@ package org.apache.lucene.gdata.server; -import java.io.IOException; -import java.io.Reader; -import java.util.Enumeration; -import java.util.Map; -import java.util.StringTokenizer; +import java.io.IOException; +import java.io.Reader; +import java.util.Enumeration; +import java.util.Map; +import java.util.StringTokenizer; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.registry.ComponentType; +import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; +import org.apache.lucene.gdata.server.registry.GDataServerRegistry; +import org.apache.lucene.gdata.storage.Storage; +import org.apache.lucene.gdata.storage.StorageController; -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.lucene.gdata.server.registry.GDataServerRegistry; - -import com.google.gdata.data.ExtensionProfile; - /** * The GDataRequest Class wraps the incoming HttpServletRequest. Needed * information coming with the HttpServletRequest can be accessed directly. It @@ -77,8 +79,8 @@ private String entryId = null; - private ExtensionProfile extensionProfile= null; - + private FeedInstanceConfigurator configurator = null; + private String entryVersion = null; private GDataRequestType type; @@ -112,12 +114,24 @@ public void initializeRequest() throws GDataRequestException { generateIdentificationProperties(); setOutputFormat(); - /* - * ExtensionProfile is used for building the Entry / Feed Instances from an inputstream or reader - */ - this.extensionProfile = GDataServerRegistry.getRegistry().getExtensionProfile(this.feedId); - if(this.extensionProfile == null) - throw new GDataRequestException("feed is not registered or extension profile could not be created"); + StorageController controller = GDataServerRegistry.getRegistry().lookup(StorageController.class,ComponentType.STORAGECONTROLLER); + try{ + Storage storage = controller.getStorage(); + String classType = storage.getFeedType(this.feedId); + /* + * ExtensionProfile and the type is used for building the Entry / Feed Instances from an inputstream or reader + * + */ + this.configurator = GDataServerRegistry.getRegistry().getFeedConfigurator(classType); + if(this.configurator == null) + throw new GDataRequestException("feed is not registered or extension profile could not be created"); + + }catch (Exception e) { + throw new GDataRequestException("feed is not registered or extension profile could not be created"); + } + + + } /** @@ -203,6 +217,10 @@ this.entryId = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : ""; this.entryVersion = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : ""; + + + + } @@ -263,7 +281,7 @@ public String getSelfId() { StringBuilder builder = new StringBuilder(); builder.append(buildRequestIDString(false)); - + builder.append("?"); builder.append(getQueryString()); return builder.toString(); @@ -275,45 +293,58 @@ * @return the id of the next page */ public String getNextId() { - // StringBuilder builder = new StringBuilder(); - // builder.append(buildRequestIDString()); - // - // builder.append(getQueryString()); - // - // if(this.request.getParameter(START_INDEX_NEXT_PAGE_PARAMETER)== - // null){ - // builder.append("&").append(START_INDEX_NEXT_PAGE_PARAMETER).append("="); - // builder.append(DEFAULT_ITEMS_PER_PAGE+1); - // } - // else{ - // - // int next = 0; - // try{ - // next = - // Integer.parseInt(this.request.getParameter(START_INDEX_NEXT_PAGE_PARAMETER)); - // }catch (Exception e) { - // // - // } - // - // if(next < 0) - // builder.append(DEFAULT_ITEMS_PER_PAGE+1); - // else - // builder.append(next+DEFAULT_ITEMS_PER_PAGE); - // int pos = builder.indexOf(START_INDEX_NEXT_PAGE_PARAMETER); - // boolean end = builder.lastIndexOf("&",pos) < pos; - // builder.replace(pos+START_INDEX_NEXT_PAGE_PARAMETER.length()+1,pos+START_INDEX_NEXT_PAGE_PARAMETER.length()+3,""+next); - // - // - // System.out.println(end); - // } - // - // - // - // return builder.toString(); - return buildRequestIDString(false); + StringBuilder builder = new StringBuilder(); + builder.append(buildRequestIDString(false)); + builder.append("?"); + + + Enumeration parameters = this.request.getParameterNames(); + while (parameters.hasMoreElements()) { + String element = (String) parameters.nextElement(); + String[] values = this.request.getParameterValues(element); + for (int i = 0; i < values.length; i++) { + + builder.append(element).append("="); + if(element.equals(START_INDEX_NEXT_PAGE_PARAMETER)){ + int tempVal = DEFAULT_START_INDEX; + try{ + tempVal = Integer.parseInt(values[i]); + }catch (Exception e) { + LOG.info("Can not parse StartIndex -- use defaut"); + } + builder.append(tempVal+getItemsPerPage()); + break; + } + + builder.append(values[i]); + + } + if(parameters.hasMoreElements()) + builder.append("&"); + + } + if(this.request.getParameter(ITEMS_PER_PAGE_PARAMETER)== null){ + if(builder.charAt(builder.length()-1) != '?') + builder.append('&'); + builder.append(ITEMS_PER_PAGE_PARAMETER).append("=").append(DEFAULT_ITEMS_PER_PAGE); + } + if(this.request.getParameter(START_INDEX_NEXT_PAGE_PARAMETER)== + null){ + builder.append('&'); + builder.append(START_INDEX_NEXT_PAGE_PARAMETER).append("="); + builder.append(DEFAULT_ITEMS_PER_PAGE+1); + } + + + + + return builder.toString(); - } + } + + + private String buildRequestIDString(boolean endingSlash) { StringBuilder builder = new StringBuilder("http://"); builder.append(this.request.getHeader("Host")); @@ -340,7 +371,7 @@ if (this.request.getParameter(ITEMS_PER_PAGE_PARAMETER) != null) return retVal; - String tempString = (retVal == null ? "?" + ITEMS_PER_PAGE_PARAMETER + String tempString = (retVal == null ? ITEMS_PER_PAGE_PARAMETER + "=" + DEFAULT_ITEMS_PER_PAGE : "&" + ITEMS_PER_PAGE_PARAMETER + "=" + DEFAULT_ITEMS_PER_PAGE); @@ -432,11 +463,10 @@ return !this.isFeedRequested(); } - /** - * @return - the extensionProfile for the requested resource - */ - public ExtensionProfile getExtensionProfile() { - return this.extensionProfile; - } - + /** + * @return the configuration for this request + */ + public FeedInstanceConfigurator getConfigurator(){ + return this.configurator; + } } Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/data/GDataUser.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/data/GDataUser.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/data/GDataUser.java (revision 0) @@ -0,0 +1,248 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.data; + +import java.net.URL; +import java.util.HashSet; +import java.util.Set; + +/** + * Represents a GData User + * + * @author Simon Willnauer + * + */ +public class GDataUser { + private final String username; + + private String authorname; + + private String authorMail; + + private URL authorLink; + + private String password; + + private Set roles = new HashSet(4); + + + + /** + * @return - the password + */ + public String getPassword() { + return this.password; + } + + /** + * @param password - + * the user Password + */ + public void setPassword(String password) { + this.password = password; + } + + /** + * @return - the username + */ + public String getUsername() { + return this.username; + } + + /** + * Creates a new GDATAUser + * + * @param username - + * the username (primary id) + */ + public GDataUser(final String username) { + if (username == null) + throw new IllegalArgumentException("Username must not be null"); + this.username = username; + this.roles.add(UserRole.USER); + + } + + /** + * @return - the http link specified for the author + */ + public URL getAuthorLink() { + return this.authorLink; + } + + /** + * @param authorLink + */ + public void setAuthorLink(URL authorLink) { + this.authorLink = authorLink; + } + + /** + * @return - the authors mail address + */ + public String getAuthorMail() { + return this.authorMail; + } + + /** + * @param authorMail - + * the authors mail address + */ + public void setAuthorMail(String authorMail) { + this.authorMail = authorMail; + } + + /** + * @return - the name specified as being the author name + */ + public String getAuthorname() { + return this.authorname; + } + + /** + * @param authorname - + * the name specified as being the author name + */ + public void setAuthorname(String authorname) { + this.authorname = authorname; + } + + /** + * Adds the given role to the role list + * + * @param role - + * the role to add to the role list + */ + public void setRole(UserRole role) { + if (role == null) + return; + this.roles.add(role); + } + + /** + * @return - the set containing all roles + */ + public Set getRoles() { + return this.roles; + } + + /** + * @param role - + * the role to check + * @return true if the role list contains the given role + */ + public boolean isUserInRole(UserRole role) { + if (role == null) + return false; + return this.roles.contains(role); + } + + /** + * @see GDataUser#setRolesAsInt(int) + * @return - the integer representation for the user roles + */ + public int getRolesAsInt() { + // 1 as the Userrole is always set + int bits = 1; + for (UserRole role : this.roles) { + if (role == UserRole.ENTRYAMINISTRATOR) + bits ^= 2; + else if (role == UserRole.FEEDAMINISTRATOR) + bits ^= 4; + else if (role == UserRole.USERADMINISTRATOR) + bits ^= 8; + + } + return bits; + + } + + /** + * Sets the roles from a int representation. + *
    + *
  1. The fist bit set indicates a {@link UserRole#USER}
  2. + *
  3. The second bit set indicates a {@link UserRole#ENTRYAMINISTRATOR}
  4. + *
  5. The third bit set indicates a {@link UserRole#FEEDAMINISTRATOR}
  6. + *
  7. The forth bit set indicates a {@link UserRole#USERADMINISTRATOR}
  8. + *
      + * This method will only set roles, will not remove roles! + * + * @param i - the integer used to set the roles + */ + public void setRolesAsInt(int i) { + + if ((i & 2) > 0) + this.roles.add(UserRole.ENTRYAMINISTRATOR); + if ((i & 4) > 0) + this.roles.add(UserRole.FEEDAMINISTRATOR); + if ((i & 8) > 0) + this.roles.add(UserRole.USERADMINISTRATOR); + + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof GDataUser) || o == null) + return false; + GDataUser toCompare = (GDataUser) o; + if (this.username.equals(toCompare.username)) + return true; + return false; + + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + int ret = 37; + ret = 9 * ret + this.username.hashCode(); + return ret; + } + + /** + * This enum respesents all userroles a user can have. + * + * @author Simon Willnauer + * + */ + public enum UserRole { + + /** + * Can create / alter user + */ + USERADMINISTRATOR, + + /** + * Can create / alter feeds + */ + FEEDAMINISTRATOR, + /** + * Can create / alter entries + */ + ENTRYAMINISTRATOR, + /** + * can create / alter his own feed entries + */ + USER + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/data/ServerBaseEntry.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/data/ServerBaseEntry.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/data/ServerBaseEntry.java (revision 0) @@ -0,0 +1,65 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * 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.apache.lucene.gdata.data; + +import java.util.LinkedList; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.data.Link; + +/** + * @author Simon Willnauer + * + */ +public class ServerBaseEntry extends BaseEntry { + + /** + * + */ + public ServerBaseEntry() { + super(); + + } + + /** + * @param arg0 + */ + + @SuppressWarnings("unchecked") + public ServerBaseEntry(BaseEntry arg0) { + super(arg0); + this.links = new LinkedList(); + } + + /** + * @see com.google.gdata.data.BaseEntry#declareExtensions(com.google.gdata.data.ExtensionProfile) + */ + @Override + public void declareExtensions(ExtensionProfile arg0) { + this.source.declareExtensions(arg0); + } + + /** + * @param link + */ + @SuppressWarnings("unchecked") + public void addLink(final Link link){ + this.links.add(link); + } + +} Index: contrib/gdata-server/src/java/lucenestorage.properties.xml =================================================================== --- contrib/gdata-server/src/java/lucenestorage.properties.xml (revision 413530) +++ contrib/gdata-server/src/java/lucenestorage.properties.xml (working copy) @@ -1,11 +1,12 @@ - - - -Lucene Storage Properties -20 -20 -20 -/tmp/storage/ -true -false - + + + +Lucene Storage Properties +20 +20 +20 +true +/tmp/storage/ +true +false +