lucene-java-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cutt...@apache.org
Subject svn commit: r412574 [3/4] - in /lucene/java/trunk: ./ contrib/gdata-server/ contrib/gdata-server/lib/ contrib/gdata-server/src/ contrib/gdata-server/src/java/ contrib/gdata-server/src/java/org/ contrib/gdata-server/src/java/org/apache/ contrib/gdata-se...
Date Wed, 07 Jun 2006 21:56:29 GMT
Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageEntryWrapper.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageEntryWrapper.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageEntryWrapper.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageEntryWrapper.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,188 @@
+/** 
+ * 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 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 
+ * be stored inside the index. 
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public class StorageEntryWrapper implements Comparable<StorageEntryWrapper> { 
+    private static final String INTERNAL_ENCODING = "UTF-8"; 
+ 
+    /** 
+     * lucene field name Entry id 
+     */ 
+    public final static String FIELD_ENTRY_ID = "entryId"; 
+ 
+    /** 
+     * lucene field name feed id 
+     */ 
+    public final static String FIELD_FEED_ID = "feedId"; 
+ 
+    /** 
+     * lucene field name entry content 
+     */ 
+    public final static String FIELD_CONTENT = "content"; 
+ 
+    /** 
+     * lucene field name creating timestamp 
+     */ 
+    public final static String FIELD_TIMESTAMP = "timestamp"; 
+ 
+    private final String entryId; 
+ 
+    private final String feedId; 
+ 
+    private final String content; 
+ 
+    private final transient BaseEntry entry; 
+ 
+    private final Long timestamp; 
+ 
+    private transient Document document; 
+ 
+    private StorageOperation operation; 
+ 
+    private final ExtensionProfile profile; 
+ 
+    /** 
+     * Creates a new StorageEntryWrapper. 
+     *  
+     * @param entry - 
+     *            the entry to wrap 
+     * @param feedId - 
+     *            the feed id 
+     * @param operation - 
+     *            the StorageOperation 
+     * @param profile - 
+     *            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 { 
+        this.entry = entry; 
+        this.operation = operation; 
+        this.entryId = entry.getId(); 
+        this.feedId = feedId; 
+        this.profile = profile; 
+        this.content = buildContent(); 
+        this.timestamp = new Long(System.currentTimeMillis()); 
+ 
+    } 
+ 
+    private String buildContent() throws IOException { 
+        StringWriter writer = new StringWriter(); 
+        XmlWriter xmlWriter = new XmlWriter(writer, INTERNAL_ENCODING); 
+        this.entry.generateAtom(xmlWriter, this.profile); 
+        return writer.toString(); 
+ 
+    } 
+ 
+    /** 
+     * @return - the lucene document representing the entry 
+     */ 
+    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, 
+                Field.Index.UN_TOKENIZED)); 
+        this.document.add(new Field("feedId", 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(), 
+                Field.Store.YES, Field.Index.UN_TOKENIZED)); 
+ 
+        return this.document; 
+ 
+    } 
+ 
+    /** 
+     * @return - the wrapped entry 
+     */ 
+    public BaseEntry getEntry() { 
+        return this.entry; 
+    } 
+ 
+    /** 
+     * @return - the entry id 
+     */ 
+    public String getEntryId() { 
+        return this.entryId; 
+    } 
+ 
+    /** 
+     * @return - the feed id 
+     */ 
+    public String getFeedId() { 
+        return this.feedId; 
+    } 
+ 
+    /** 
+     * Storage operations 
+     *  
+     * @author Simon Willnauer 
+     *  
+     */ 
+    public static enum StorageOperation { 
+        /** 
+         * delete 
+         */ 
+        DELETE, 
+        /** 
+         * update 
+         */ 
+        UPDATE, 
+        /** 
+         * insert 
+         */ 
+        INSERT 
+    } 
+ 
+    /** 
+     * @return the specified storage operation 
+     */ 
+    public StorageOperation getOperation() { 
+        return this.operation; 
+    } 
+ 
+    /** 
+     * @see java.lang.Comparable#compareTo(T) 
+     */ 
+    public int compareTo(StorageEntryWrapper arg0) { 
+        return arg0.timestamp == this.timestamp ? 0 
+                : (arg0.timestamp > this.timestamp ? 1 : -1); 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageImplementation.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageImplementation.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageImplementation.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageImplementation.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,259 @@
+/** 
+ * 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.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; 
+ 
+        } 
+ 
+        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<StorageQuery> query = null; 
+        try { 
+            query = this.controller.getStorageQuery(); 
+            List<BaseEntry> 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<StorageQuery> 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<BaseEntry> getEntries(List<String> 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; 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageModifier.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageModifier.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageModifier.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageModifier.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,236 @@
+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 
+ * 
+ */ 
+public class StorageModifier { 
+    protected static final Log LOG = LogFactory.getLog(StorageModifier.class); 
+ 
+    private final List<Term> deletedDocumentQueue; 
+    private final List<Term> deletedForUpdateDocumentQueue; 
+ 
+    private final Map<String,Document> 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<Term>(); 
+        this.deletedForUpdateDocumentQueue = new LinkedList<Term>(); 
+        this.documentMap = new HashMap<String,Document>(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  
+     * 
+     */ 
+    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<Document> 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++; 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageQuery.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageQuery.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageQuery.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageQuery.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,342 @@
+/** 
+ * 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.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. 
+ * <p> 
+ * 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. 
+ * </p> 
+ * @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<String> 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. 
+     * <p> 
+     * 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. 
+     * </p> 
+     * <p> 
+     * The entries will be searched in a feed context specified by the given 
+     * feed ID 
+     * </p> 
+     *  
+     *  
+     * @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<BaseEntry> getLatestFeedQuery(final String feedId, 
+            final int resultCount, final int startIndex, 
+            final ExtensionProfile profil) throws IOException, 
+            FeedNotFoundException, ParseException { 
+        List<BaseEntry> returnList = new ArrayList<BaseEntry>(resultCount); 
+        List<StorageEntryWrapper> 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. 
+     * <p> 
+     * The Entry will be searched in a feed context specified by the given feed 
+     * ID 
+     * </p> 
+     *  
+     * @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 <code>null</code> 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. 
+     * <p> 
+     * The entries will be searched in a feed context specified by the given 
+     * feed ID 
+     * </p> 
+     *  
+     * @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<BaseEntry> entryQuery(List<String> entryIds, 
+            final String feedId, final ExtensionProfile profil) 
+            throws IOException, FeedNotFoundException, ParseException { 
+        List<BaseEntry> resultList = new ArrayList<BaseEntry>(entryIds.size()); 
+        List<String> searchList = new ArrayList<String>(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(); 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/StorageConfigurator.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/StorageConfigurator.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/StorageConfigurator.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/StorageConfigurator.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,144 @@
+/** 
+ * 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 <i>lucenestorage.properties.xml</i> 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 <code>true</code> if the storage is supposed to keep the 
+     *         recovering files. 
+     */ 
+    public boolean isKeepRecoveredFiles() { 
+        return this.keepRecoveredFiles; 
+    } 
+ 
+    /** 
+     * @return <code>true</code> 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; 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/package.html
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/package.html?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/package.html (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/package.html Wed Jun  7 14:56:25 2006
@@ -0,0 +1,10 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> 
+<html> 
+<head> 
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 
+   <meta name="Author" content="Simon Willnauer"> 
+</head> 
+<body> 
+Lucene Storage utils 
+</body> 
+</html> 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/package.html
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/package.html?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/package.html (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/package.html Wed Jun  7 14:56:25 2006
@@ -0,0 +1,10 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> 
+<html> 
+<head> 
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 
+   <meta name="Author" content="Simon Willnauer"> 
+</head> 
+<body> 
+Lucene storage implementation  
+</body> 
+</html> 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/ReferenceCounter.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/ReferenceCounter.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/ReferenceCounter.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/ReferenceCounter.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,77 @@
+/** 
+ * 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.util; 
+ 
+import java.util.concurrent.atomic.AtomicInteger; 
+ 
+/** 
+ * A reference counting utility. This is use to keep track of released objects 
+ * of <code>Type</code>. 
+ *  
+ * @author Simon Willnauer 
+ * @param <Type> - 
+ *            the type of the object 
+ *  
+ */ 
+public abstract class ReferenceCounter<Type> { 
+    protected final Type resource; 
+ 
+    private AtomicInteger refcounter = new AtomicInteger(); 
+ 
+    /** 
+     * @param resource - 
+     *            the resouce to track 
+     *  
+     */ 
+    public ReferenceCounter(Type resource) { 
+        this.resource = resource; 
+    } 
+ 
+    /** 
+     *  
+     * Decrements the reference. If no references remain the 
+     * {@link ReferenceCounter#close()} method will be inoked; 
+     */ 
+    public final void decrementRef() { 
+        if (this.refcounter.decrementAndGet() == 0) 
+            close(); 
+    } 
+ 
+    /** 
+     * A custom implementation. Performs an action if no reference remaining 
+     *  
+     */ 
+    protected abstract void close(); 
+ 
+    /** 
+     * Increments the reference 
+     *  
+     * @return the refernece object 
+     */ 
+    public final ReferenceCounter<Type> increamentReference() { 
+        this.refcounter.incrementAndGet(); 
+        return this; 
+    } 
+ 
+    /** 
+     * @return - the resource to keep track of 
+     */ 
+    public final Type get() { 
+        return this.resource; 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/package.html
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/package.html?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/package.html (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/package.html Wed Jun  7 14:56:25 2006
@@ -0,0 +1,10 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> 
+<html> 
+<head> 
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 
+   <meta name="Author" content="Simon Willnauer"> 
+</head> 
+<body> 
+Storage Configuration 
+</body> 
+</html> 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/package.html
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/package.html?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/package.html (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/package.html Wed Jun  7 14:56:25 2006
@@ -0,0 +1,10 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> 
+<html> 
+<head> 
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 
+   <meta name="Author" content="Simon Willnauer"> 
+</head> 
+<body> 
+Feed / Enty storage  
+</body> 
+</html> 

Added: lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,403 @@
+/** 
+ * 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 javax.servlet.http.HttpServletRequest; 
+ 
+import junit.framework.TestCase; 
+ 
+import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; 
+import org.apache.lucene.gdata.server.GDataRequest.OutputFormat; 
+import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; 
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry; 
+import org.easymock.MockControl; 
+ 
+import com.google.gdata.data.ExtensionProfile; 
+import com.google.gdata.data.Feed; 
+ 
+/** 
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public class TestGDataRequest extends TestCase { 
+    private HttpServletRequest request; 
+ 
+    private MockControl control; 
+ 
+    private GDataRequest feedRequest; 
+ 
+    @Override 
+    protected void setUp() throws Exception { 
+        FeedInstanceConfigurator configurator = new FeedInstanceConfigurator(); 
+        configurator.setFeedType(Feed.class); 
+        configurator.setFeedId("feed"); 
+        configurator.setExtensionProfileClass(ExtensionProfile.class); 
+        GDataServerRegistry.getRegistry().registerFeed(configurator); 
+        this.control = MockControl.createControl(HttpServletRequest.class); 
+        this.request = (HttpServletRequest) this.control.getMock(); 
+        this.feedRequest = new GDataRequest(this.request,GDataRequestType.GET); 
+         
+    } 
+ 
+    protected void tearDown() throws Exception { 
+        super.tearDown(); 
+        this.control.reset(); 
+    } 
+ 
+    public void testConstructor() { 
+        try { 
+            new GDataRequest(null,GDataRequestType.GET); 
+            fail("IllegalArgumentException expected"); 
+        } catch (IllegalArgumentException e) { 
+            //  
+        } 
+        try { 
+            new GDataRequest(null,null); 
+            fail("IllegalArgumentException expected"); 
+        } catch (IllegalArgumentException e) { 
+            //  
+        } 
+        try { 
+            new GDataRequest(this.request,null); 
+            fail("IllegalArgumentException expected"); 
+        } catch (IllegalArgumentException e) { 
+            //  
+        } 
+    } 
+ 
+    public void testGetFeedId() throws GDataRequestException { 
+ 
+        this.control.expectAndDefaultReturn(this.request.getPathInfo(), 
+                "/feed/1/1"); 
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                null); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+        assertEquals("feedID", this.feedRequest.getFeedId(), "feed"); 
+        this.control.reset(); 
+ 
+    } 
+ 
+    public void testEmptyPathInfo() { 
+        this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/"); 
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                null); 
+        this.control.replay(); 
+        try { 
+            this.feedRequest.initializeRequest(); 
+ 
+            fail("FeedRequestException expected"); 
+        } catch (GDataRequestException e) { 
+            // expected 
+        } catch (Exception e) { 
+            fail("FeedRequestException expected"); 
+        } 
+ 
+    } 
+ 
+    public void testGetFeedIdWithoutEntry() throws GDataRequestException { 
+        this.control 
+                .expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); 
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                null); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+        assertEquals("feedID", this.feedRequest.getFeedId(), "feed"); 
+    } 
+ 
+    public void testGetEntyId() throws GDataRequestException { 
+ 
+        this.control.expectAndDefaultReturn(this.request.getPathInfo(), 
+                "/feed/1/15"); 
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                null); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+        assertEquals("entryid", this.feedRequest.getEntryId(), "1"); 
+        assertEquals("feedId", this.feedRequest.getFeedId(), "feed"); 
+        assertEquals("entryid", this.feedRequest.getEntryVersion(), "15"); 
+        this.control.reset(); 
+ 
+    } 
+ 
+    public void testSetResponseFormatAtom() throws GDataRequestException { 
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                "atom"); 
+        this.control 
+                .expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+        assertEquals("ResponseFromat Atom", this.feedRequest 
+                .getRequestedResponseFormat(), OutputFormat.ATOM); 
+        this.control.reset(); 
+    } 
+ 
+    public void testSetResponseFormatRSS() throws GDataRequestException { 
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                "rss"); 
+        this.control 
+                .expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+        assertEquals("ResponseFromat RSS", this.feedRequest 
+                .getRequestedResponseFormat(), OutputFormat.RSS); 
+        this.control.reset(); 
+    } 
+ 
+    public void testSetResponseFormatKeepAtom() throws GDataRequestException { 
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                "fooBar"); 
+        this.control 
+                .expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+        assertEquals("ResponseFromat Atom", this.feedRequest 
+                .getRequestedResponseFormat(), OutputFormat.ATOM); 
+        this.control.reset(); 
+    } 
+ 
+    public void testSetResponseFormatNull() throws GDataRequestException { 
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                null); 
+ 
+        this.control 
+                .expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+        assertEquals("ResponseFromat Atom", this.feedRequest 
+                .getRequestedResponseFormat(), OutputFormat.ATOM); 
+        this.control.reset(); 
+    } 
+ 
+    public void testGetItemsPerPage() throws GDataRequestException { 
+        this.control.expectAndReturn(this.request.getParameter("max-results"), 
+                null); 
+        this.control.replay(); 
+        assertEquals("default value 25", 25, this.feedRequest.getItemsPerPage()); 
+        this.control.verify(); 
+        this.control.reset(); 
+ 
+        this.control.expectAndReturn(this.request.getParameter("max-results"), 
+                "24", 2); 
+        this.control.replay(); 
+        assertEquals("24 results", 24, this.feedRequest.getItemsPerPage()); 
+        this.control.verify(); 
+        this.control.reset(); 
+         
+        this.control.expectAndReturn(this.request.getParameter("max-results"), 
+                "-1", 2); 
+        this.control.replay(); 
+        assertEquals("25 results", 25, this.feedRequest.getItemsPerPage()); 
+        this.control.verify(); 
+        this.control.reset(); 
+ 
+        this.control.expectAndReturn(this.request.getParameter("max-results"), 
+                "helloworld", 2); 
+        this.control.replay(); 
+        assertEquals("25 results", 25, this.feedRequest.getItemsPerPage()); 
+        this.control.verify(); 
+        this.control.reset(); 
+    } 
+     
+    public void testGetSelfId() throws GDataRequestException{ 
+        String host = "www.apache.org"; 
+        String feedAndEntryID = "/feed/entryid"; 
+        String queryString = "?max-results=25"; 
+        this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host); 
+        this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/host/feed/entryId/15"); 
+        this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/entryId/15"); 
+        this.control.expectAndReturn(this.request.getParameter("max-results"),"25",2); 
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                null); 
+        this.control.expectAndDefaultReturn(this.request.getQueryString(), 
+                queryString); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+        String selfID = "http://"+host+"/host/feed/entryId/15"+queryString; 
+     
+        assertEquals("Self ID",selfID,this.feedRequest.getSelfId()); 
+        this.control.reset(); 
+         
+         
+        queryString = "?alt=rss&max-results=25"; 
+        this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host); 
+        this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/host/feed/entryId/15"); 
+        this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/entryId/15"); 
+        this.control.expectAndReturn(this.request.getParameter("max-results"),"25",2); 
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                null); 
+        this.control.expectAndDefaultReturn(this.request.getQueryString(), 
+                queryString); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+        selfID = "http://"+host+"/host/feed/entryId/15"+queryString; 
+     
+        assertEquals("Self ID",selfID,this.feedRequest.getSelfId()); 
+        this.control.reset(); 
+         
+        queryString = ""; 
+        this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host); 
+        this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/host/feed/entryId/15"); 
+        this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/entryId/15"); 
+        this.control.expectAndDefaultReturn(this.request.getParameter("max-results"),null); 
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                null); 
+        this.control.expectAndDefaultReturn(this.request.getQueryString(), 
+                null); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+        selfID = "http://"+host+"/host/feed/entryId/15"+"?max-results=25"; 
+     
+        assertEquals("Self ID",selfID,this.feedRequest.getSelfId()); 
+        this.control.reset(); 
+    } 
+     
+    public void testGetQueryString(){ 
+        String maxResults  = "max-results=25"; 
+        String queryString = "?"+maxResults; 
+        this.control.expectAndReturn(this.request.getParameter("max-results"),"25",2); 
+         
+        this.control.expectAndDefaultReturn(this.request.getQueryString(), 
+                queryString); 
+        this.control.replay(); 
+         
+        assertEquals(queryString,this.feedRequest.getQueryString()); 
+        this.control.reset(); 
+        // test no result defined 
+        queryString = "?alt=rss"; 
+        this.control.expectAndDefaultReturn(this.request.getParameter("max-results"),null); 
+         
+        this.control.expectAndDefaultReturn(this.request.getQueryString(), 
+                queryString); 
+        this.control.replay(); 
+         
+        assertEquals(queryString+"&"+maxResults,this.feedRequest.getQueryString()); 
+        this.control.reset(); 
+         
+//         test no result defined && query == null 
+        queryString = null; 
+        this.control.expectAndDefaultReturn(this.request.getParameter("max-results"),null); 
+         
+        this.control.expectAndDefaultReturn(this.request.getQueryString(), 
+                queryString); 
+        this.control.replay(); 
+         
+        assertEquals("?"+maxResults,this.feedRequest.getQueryString()); 
+        this.control.reset(); 
+     
+    } 
+     
+    public void testIsFeedRequest() throws GDataRequestException{ 
+        String host = "www.apache.org"; 
+        String feedAndEntryID = "/feed"; 
+         
+        this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host); 
+        this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/host/feed"); 
+        this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed"); 
+         
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                null); 
+        this.control.expectAndDefaultReturn(this.request.getQueryString(), 
+                null); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+         
+     
+        assertTrue(this.feedRequest.isFeedRequested()); 
+        assertFalse(this.feedRequest.isEntryRequested()); 
+        this.control.reset(); 
+         
+        host = "www.apache.org"; 
+        feedAndEntryID = "/feed/1"; 
+         
+        this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host); 
+        this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/host/feed/1"); 
+        this.control.expectAndDefaultReturn(this.request.getPathInfo(),feedAndEntryID); 
+         
+        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+                null); 
+        this.control.expectAndDefaultReturn(this.request.getQueryString(), 
+                null); 
+        this.control.replay(); 
+        this.feedRequest.initializeRequest(); 
+         
+     
+        assertFalse(this.feedRequest.isFeedRequested()); 
+        assertTrue(this.feedRequest.isEntryRequested()); 
+        this.control.reset(); 
+         
+         
+    } 
+    public void testIsEntryRequest(){ 
+         
+    } 
+     
+    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(); 
+//         
+//         
+//        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.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); 
+//        this.control.replay(); 
+//        this.feedRequest.initializeRequest(); 
+//        startIndex = "&start-index=51"; 
+//        nextID = "http://"+host+"/feed"+queryString+startIndex; 
+//     
+//        assertEquals("Next ID 51",nextID,this.feedRequest.getNextId()); 
+//        this.control.reset(); 
+//         
+//        queryString = ""; 
+//        this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host); 
+//        this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/entryId/15"); 
+//        this.control.expectAndDefaultReturn(this.request.getParameter("max-results"),null); 
+//        this.control.expectAndDefaultReturn(this.request.getParameter("alt"), 
+//                null); 
+//        this.control.expectAndDefaultReturn(this.request.getQueryString(), 
+//                null); 
+//        this.control.replay(); 
+//        this.feedRequest.initializeRequest(); 
+//        selfID = "http://"+host+"/feed"+"?max-results=25"; 
+//     
+//        assertEquals("Self ID",selfID,this.feedRequest.getSelfId()); 
+//        this.control.reset(); 
+    } 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,161 @@
+package org.apache.lucene.gdata.server; 
+ 
+import java.io.IOException; 
+import java.io.PrintWriter; 
+import java.io.StringWriter; 
+ 
+import javax.servlet.http.HttpServletResponse; 
+ 
+import junit.framework.TestCase; 
+ 
+import org.apache.lucene.gdata.server.GDataRequest.OutputFormat; 
+import org.easymock.MockControl; 
+ 
+import com.google.gdata.data.Entry; 
+import com.google.gdata.data.ExtensionProfile; 
+import com.google.gdata.data.Feed; 
+import com.google.gdata.data.PlainTextConstruct; 
+/** 
+ *  
+ * @author Simon Willnauer 
+ * 
+ */ 
+public class TestGDataResponse extends TestCase { 
+    private GDataResponse response; 
+    private HttpServletResponse httpResponse; 
+    private MockControl control; 
+    private static String generatedFeedAtom = "<?xml version='1.0'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'><entry><title type='text'>Test</title></entry></feed>"; 
+    private static String generatedEntryAtom = "<?xml version='1.0'?><entry xmlns='http://www.w3.org/2005/Atom'><title type='text'>Test</title></entry>"; 
+    private static String generatedFeedRSS = "<?xml version='1.0'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' version='2.0'><channel><description></description><item><title>Test</title></item></channel></rss>"; 
+    private static String generatedEntryRSS = "<?xml version='1.0'?><item xmlns:atom='http://www.w3.org/2005/Atom'><title>Test</title></item>"; 
+    protected void setUp() throws Exception { 
+        this.control = MockControl.createControl(HttpServletResponse.class); 
+        this.httpResponse = (HttpServletResponse)this.control.getMock(); 
+        this.response = new GDataResponse(this.httpResponse); 
+         
+    } 
+ 
+    protected void tearDown() throws Exception { 
+        super.tearDown(); 
+    } 
+     
+     
+    public void testConstructor(){ 
+        try{ 
+        new GDataResponse(null); 
+        fail("IllegalArgumentExceptin expected"); 
+        }catch (IllegalArgumentException e) { 
+            // TODO: handle exception 
+        } 
+    } 
+    /* 
+     * Test method for 'org.apache.lucene.gdata.server.GDataResponse.sendResponse(BaseFeed, ExtensionProfile)' 
+     */ 
+    public void testSendResponseBaseFeedExtensionProfile() throws IOException { 
+        try{ 
+            Feed f = null; 
+            this.response.sendResponse(f,new ExtensionProfile()); 
+            fail("Exception expected"); 
+        }catch (IllegalArgumentException e) { 
+            // 
+        } 
+         
+        try{ 
+            Feed f = createFeed(); 
+            this.response.sendResponse(f,null); 
+            fail("Exception expected"); 
+        }catch (IllegalArgumentException e) { 
+            // 
+        } 
+        StringWriter stringWriter = new StringWriter(); 
+        PrintWriter writer = new PrintWriter(stringWriter); 
+         
+        this.control.expectAndReturn(this.httpResponse.getWriter(),writer); 
+        this.response.setOutputFormat(OutputFormat.ATOM); 
+        this.control.replay(); 
+         
+        this.response.sendResponse(createFeed(),new ExtensionProfile 
+                ()); 
+        assertEquals("Simple XML representation",stringWriter.toString(),generatedFeedAtom); 
+        this.control.reset(); 
+         
+        stringWriter = new StringWriter(); 
+        writer = new PrintWriter(stringWriter); 
+         
+        this.control.expectAndReturn(this.httpResponse.getWriter(),writer); 
+        this.response.setOutputFormat(OutputFormat.RSS); 
+        this.control.replay(); 
+         
+        this.response.sendResponse(createFeed(),new ExtensionProfile 
+                ()); 
+        assertEquals("Simple XML representation",stringWriter.toString(),generatedFeedRSS); 
+         
+         
+         
+ 
+    } 
+ 
+    /* 
+     * Test method for 'org.apache.lucene.gdata.server.GDataResponse.sendResponse(BaseEntry, ExtensionProfile)' 
+     */ 
+    public void testSendResponseBaseEntryExtensionProfile() throws IOException { 
+        try{ 
+            Entry e = null; 
+            this.response.sendResponse(e,new ExtensionProfile()); 
+            fail("Exception expected"); 
+        }catch (IllegalArgumentException e) { 
+            // 
+        } 
+        try{ 
+            Entry e = createEntry(); 
+            this.response.sendResponse(e,null); 
+            fail("Exception expected"); 
+        }catch (IllegalArgumentException e) { 
+            // 
+        } 
+//        // test Atom output 
+        StringWriter stringWriter = new StringWriter(); 
+        PrintWriter writer = new PrintWriter(stringWriter); 
+         
+        this.control.expectAndReturn(this.httpResponse.getWriter(),writer); 
+        this.response.setOutputFormat(OutputFormat.ATOM); 
+        this.control.replay(); 
+         
+        this.response.sendResponse(createEntry(),new ExtensionProfile 
+                ()); 
+        assertEquals("Simple XML representation ATOM",stringWriter.toString(),generatedEntryAtom); 
+         
+        // test rss output 
+        this.control.reset(); 
+        stringWriter = new StringWriter(); 
+        writer = new PrintWriter(stringWriter); 
+         
+        this.control.expectAndReturn(this.httpResponse.getWriter(),writer); 
+        this.response.setOutputFormat(OutputFormat.RSS); 
+        this.control.replay(); 
+         
+        this.response.sendResponse(createEntry(),new ExtensionProfile 
+                ()); 
+         
+        assertEquals("Simple XML representation RSS",stringWriter.toString(),generatedEntryRSS); 
+         
+         
+         
+    } 
+     
+    /* create a simple feed */ 
+    private Feed createFeed(){ 
+        Feed feed = new Feed(); 
+         
+        feed.getEntries().add(createEntry()); 
+         
+        return feed; 
+    } 
+    /* create a simple entry */ 
+    private Entry createEntry(){ 
+        Entry e = new Entry(); 
+        e.setTitle(new PlainTextConstruct("Test")); 
+        return e; 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml (added)
+++ lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml Wed Jun  7 14:56:25 2006
@@ -0,0 +1,21 @@
+<?xml version='1.0' encoding='UTF-8'?> 
+<entry xmlns='http://www.w3.org/2005/Atom'> 
+    <id> 
+        http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/af4b5ca305c80f96f42c9af66c5b04a8473c949c 
+    </id> 
+    <published>2006-12-23T00:00:00.000Z</published> 
+    <updated>2006-05-23T16:42:48.000Z</updated> 
+    <category scheme='http://schemas.google.com/g/2005#kind' 
+        term='http://schemas.google.com/g/2005#event'> 
+    </category> 
+    <summary type='html'> 
+        When: 2006-12-23 to 2006-12-31 America/Los_Angeles&lt;br> 
+    </summary> 
+    <link rel='alternate' type='text/html' 
+        href='http://www.google.com/calendar/event?eid=YWY0YjVjYTMwNWM4MGY5NmY0MmM5YWY2NmM1YjA0YTg0NzNjOTQ5YyBzaW1vbi53aWxsbmF1ZXJAZ29vZ2xlbWFpbC5jb20' 
+        title='alternate'> 
+    </link> 
+    <link rel='self' type='application/atom+xml' 
+        href='http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/af4b5ca305c80f96f42c9af66c5b04a8473c949c'> 
+    </link> 
+</entry> 
\ No newline at end of file

Added: lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml (added)
+++ lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml Wed Jun  7 14:56:25 2006
@@ -0,0 +1,90 @@
+<?xml version='1.0' encoding='UTF-8'?> 
+<feed xmlns='http://www.w3.org/2005/Atom' 
+    xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' 
+    xmlns:gd='http://schemas.google.com/g/2005'> 
+    <id> 
+        http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic 
+    </id> 
+    <updated>2006-05-27T11:47:55.000Z</updated> 
+    <title type='text'>Simon Willnauer</title> 
+    <subtitle type='text'>Simon Willnauer</subtitle> 
+    <link rel='http://schemas.google.com/g/2005#feed' 
+        type='application/atom+xml' 
+        href='http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic'> 
+    </link> 
+    <link rel='self' type='application/atom+xml' 
+        href='http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic?max-results=25'> 
+    </link> 
+    <link rel='next' type='application/atom+xml' 
+        href='http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic?start-index=26&amp;max-results=25'> 
+    </link> 
+    <author> 
+        <name>Simon Willnauer</name> 
+        <email>simon.willnauer@googlemail.com</email> 
+    </author> 
+    <generator version='1.0' uri='http://www.google.com/calendar'> 
+        Google Calendar 
+    </generator> 
+    <openSearch:itemsPerPage>25</openSearch:itemsPerPage> 
+    <entry> 
+        <id> 
+            http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/af4b5ca305c80f96f42c9af66c5b04a8473c949c 
+        </id> 
+        <published>2006-12-23T00:00:00.000Z</published> 
+        <updated>2006-05-23T16:42:48.000Z</updated> 
+        <category scheme='http://schemas.google.com/g/2005#kind' 
+            term='http://schemas.google.com/g/2005#event'> 
+        </category> 
+        <summary type='html'> 
+            When: 2006-12-23 to 2006-12-31 America/Los_Angeles&lt;br> 
+        </summary> 
+        <link rel='alternate' type='text/html' 
+            href='http://www.google.com/calendar/event?eid=YWY0YjVjYTMwNWM4MGY5NmY0MmM5YWY2NmM1YjA0YTg0NzNjOTQ5YyBzaW1vbi53aWxsbmF1ZXJAZ29vZ2xlbWFpbC5jb20' 
+            title='alternate'> 
+        </link> 
+        <link rel='self' type='application/atom+xml' 
+            href='http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/af4b5ca305c80f96f42c9af66c5b04a8473c949c'> 
+        </link> 
+    </entry> 
+    <entry> 
+        <id> 
+            http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/d5402951792ce690f6a45e51143deb78f4fffac4 
+        </id> 
+        <published>2006-05-26T00:00:00.000Z</published> 
+        <updated>2006-05-20T22:17:44.000Z</updated> 
+        <category scheme='http://schemas.google.com/g/2005#kind' 
+            term='http://schemas.google.com/g/2005#event'> 
+        </category> 
+        <summary type='html'> 
+            When: 2006-05-26 to 2006-05-27 America/Los_Angeles&lt;br> 
+        </summary> 
+        <link rel='alternate' type='text/html' 
+            href='http://www.google.com/calendar/event?eid=ZDU0MDI5NTE3OTJjZTY5MGY2YTQ1ZTUxMTQzZGViNzhmNGZmZmFjNCBzaW1vbi53aWxsbmF1ZXJAZ29vZ2xlbWFpbC5jb20' 
+            title='alternate'> 
+        </link> 
+        <link rel='self' type='application/atom+xml' 
+            href='http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/d5402951792ce690f6a45e51143deb78f4fffac4'> 
+        </link> 
+    </entry> 
+    <entry> 
+        <id> 
+            http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/21630e853795ea81d5e792d0ab082ad1c44256e4 
+        </id> 
+        <published>2006-06-19T14:00:00.000Z</published> 
+        <updated>2006-05-17T16:10:57.000Z</updated> 
+        <category scheme='http://schemas.google.com/g/2005#kind' 
+            term='http://schemas.google.com/g/2005#event'> 
+        </category> 
+        <summary type='html'> 
+            When: 2006-06-19 07:00:00 to 08:00:00 
+            America/Los_Angeles&lt;br> 
+        </summary> 
+        <link rel='alternate' type='text/html' 
+            href='http://www.google.com/calendar/event?eid=MjE2MzBlODUzNzk1ZWE4MWQ1ZTc5MmQwYWIwODJhZDFjNDQyNTZlNCBzaW1vbi53aWxsbmF1ZXJAZ29vZ2xlbWFpbC5jb20' 
+            title='alternate'> 
+        </link> 
+        <link rel='self' type='application/atom+xml' 
+            href='http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/21630e853795ea81d5e792d0ab082ad1c44256e4'> 
+        </link> 
+    </entry> 
+</feed> 
\ No newline at end of file

Added: lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,98 @@
+/** 
+ * 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); 
+    } 
+ 
+} 



Mime
View raw message