gdata fixes: LUCENE-653, LUCENE-654

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@432040 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2006-08-16 21:21:26 +00:00
parent d24ee28c66
commit d3629f25eb
16 changed files with 487 additions and 161 deletions

View File

@ -11,7 +11,7 @@
<property name="db4o.jar" value="db4o-5.2-java5.jar" /> <property name="db4o.jar" value="db4o-5.2-java5.jar" />
<!-- set property for third party jars --> <!-- set property for third party jars -->
<available property="db4o.jar.present" type="file" file="${gdata.lib.dir}/${db4o.jar}" value="test"/> <available property="db4o.jar.present" type="file" file="${gdata.lib.dir}/${db4o.jar}" value="test"/>
<condition property="junit.excludes" value="**/TestDb4o*.java"> <condition property="junit.excludes" value="**/db4o/**/*.java">
<not> <not>
<isset property="db4o.jar.present"/> <isset property="db4o.jar.present"/>
</not> </not>

View File

@ -18,9 +18,9 @@ package org.apache.lucene.gdata.search;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
@ -46,7 +46,7 @@ public class StandardGdataSearcher implements GDataSearcher<String> {
private final ReferenceCounter<IndexSearcher> searcher; private final ReferenceCounter<IndexSearcher> searcher;
private static final Map<String, QueryFilter> queryFilterCache = new WeakHashMap<String, QueryFilter>(); private static final Map<String, QueryFilter> queryFilterCache = new HashMap<String, QueryFilter>();
/** constructs a new GdataSearcher /** constructs a new GdataSearcher
* @param searcher - the current lucene searcher instance * @param searcher - the current lucene searcher instance
@ -77,15 +77,15 @@ public class StandardGdataSearcher implements GDataSearcher<String> {
QueryFilter filter = null; QueryFilter filter = null;
synchronized (queryFilterCache) { synchronized (queryFilterCache) {
filter = queryFilterCache.get(feedId); filter = queryFilterCache.get(feedId);
}
if (filter == null) if (filter == null)
filter = new QueryFilter(new TermQuery(new Term( filter = new QueryFilter(new TermQuery(new Term(
IndexDocument.FIELD_FEED_ID, feedId))); IndexDocument.FIELD_FEED_ID, feedId)));
IndexSearcher indexSearcher = this.searcher.get();
Hits hits = indexSearcher.search(query, filter);
synchronized (queryFilterCache) {
queryFilterCache.put(feedId, filter); queryFilterCache.put(feedId, filter);
} }
IndexSearcher indexSearcher = this.searcher.get();
Hits hits = indexSearcher.search(query, filter);
return collectHits(hits, hitcount, offset); return collectHits(hits, hitcount, offset);
} }
@ -126,7 +126,10 @@ public class StandardGdataSearcher implements GDataSearcher<String> {
} }
static void flushFilterCache() { static void flushFilterCache() {
queryFilterCache.clear(); synchronized (queryFilterCache) {
queryFilterCache.clear();
}
} }
} }

View File

@ -94,10 +94,13 @@ public class GdataCategoryStrategy extends ContentStrategy {
StringBuilder contentBuilder = new StringBuilder(); StringBuilder contentBuilder = new StringBuilder();
StringBuilder schemeBuilder = new StringBuilder(); StringBuilder schemeBuilder = new StringBuilder();
String nodeName = node.getNodeName();
/* /*
* enable more than one category element * enable more than one category element -- check the node name if
* category strategy is used with an element not named "category"
*/ */
while (node != null) { while (node != null && nodeName != null
&& nodeName.equals(node.getNodeName())) {
NamedNodeMap attributeMap = node.getAttributes(); NamedNodeMap attributeMap = node.getAttributes();
if (attributeMap == null) if (attributeMap == null)
throw new NotIndexableException( throw new NotIndexableException(

View File

@ -133,4 +133,34 @@ class GDataIndexDocument implements IndexDocument {
return this.optimizeAfter; return this.optimizeAfter;
} }
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public final boolean equals(Object obj) {
if(obj == null)
return false;
if(this == obj)
return true;
if(obj instanceof GDataIndexDocument){
GDataIndexDocument other = (GDataIndexDocument)obj;
if(this.id == null)
return false;
return this.id.equals(other.id);
}
return false;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public final int hashCode() {
if(this.id == null)
return super.hashCode();
return this.id.hashCode();
}
} }

View File

@ -21,6 +21,7 @@ import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -33,6 +34,7 @@ import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.lucene.gdata.data.ServerBaseEntry; import org.apache.lucene.gdata.data.ServerBaseEntry;
import org.apache.lucene.gdata.data.ServerBaseFeed;
import org.apache.lucene.gdata.search.GDataSearcher; import org.apache.lucene.gdata.search.GDataSearcher;
import org.apache.lucene.gdata.search.SearchComponent; import org.apache.lucene.gdata.search.SearchComponent;
import org.apache.lucene.gdata.search.StandardGdataSearcher; import org.apache.lucene.gdata.search.StandardGdataSearcher;
@ -115,10 +117,8 @@ public class IndexController implements SearchComponent, IndexEventListener,
* add a schema to the index controller and create the indexer. create * add a schema to the index controller and create the indexer. create
* directories and check out existing indexes * directories and check out existing indexes
*/ */
protected void addIndexSchema(IndexSchema schema) { protected void addIndexSchema(final IndexSchema schema) {
if (this.destroyed.get()) checkDestroyed();
throw new IllegalStateException(
"IndexController has been destroyed");
if (schema.getName() == null) if (schema.getName() == null)
throw new IllegalStateException( throw new IllegalStateException(
"schema has no name -- is not associated with any service"); "schema has no name -- is not associated with any service");
@ -142,7 +142,7 @@ public class IndexController implements SearchComponent, IndexEventListener,
} }
protected ServiceIndex createIndexer(IndexSchema schema) throws IOException { protected ServiceIndex createIndexer(final IndexSchema schema) throws IOException {
GDataIndexer indexer; GDataIndexer indexer;
File indexLocation = createIndexLocation(schema.getIndexLocation(), File indexLocation = createIndexLocation(schema.getIndexLocation(),
schema.getName()); schema.getName());
@ -166,7 +166,7 @@ public class IndexController implements SearchComponent, IndexEventListener,
/* /*
* if this fails the server must not startup!! * if this fails the server must not startup!!
*/ */
protected File createIndexLocation(String path, String name) { protected File createIndexLocation(final String path,final String name) {
if (path == null || name == null) if (path == null || name == null)
throw new GdataIndexerException( throw new GdataIndexerException(
"Path or Name of the index location is not set Path: " "Path or Name of the index location is not set Path: "
@ -205,7 +205,7 @@ public class IndexController implements SearchComponent, IndexEventListener,
return file; return file;
} }
protected boolean createIndexDirectory(File file) { protected boolean createIndexDirectory(final File file) {
/* /*
* use a lucene filename filter to figure out if there is an existing * use a lucene filename filter to figure out if there is an existing
* index in the defined directory * index in the defined directory
@ -218,10 +218,8 @@ public class IndexController implements SearchComponent, IndexEventListener,
/** /**
* @see org.apache.lucene.gdata.search.index.IndexEventListener#commitCallBack(java.lang.String) * @see org.apache.lucene.gdata.search.index.IndexEventListener#commitCallBack(java.lang.String)
*/ */
public synchronized void commitCallBack(String service) { public synchronized void commitCallBack(final String service) {
if (this.destroyed.get()) checkDestroyed();
throw new IllegalStateException(
"IndexController has been destroyed");
if(LOG.isInfoEnabled()) if(LOG.isInfoEnabled())
LOG.info("CommitCallback triggered - register new searcher for service: "+service); LOG.info("CommitCallback triggered - register new searcher for service: "+service);
/* /*
@ -245,7 +243,7 @@ public class IndexController implements SearchComponent, IndexEventListener,
* create a new ReferenceCounter for the indexSearcher. * create a new ReferenceCounter for the indexSearcher.
* The reference is already incremented before returned * The reference is already incremented before returned
*/ */
private ReferenceCounter<IndexSearcher> getNewServiceSearcher(Directory dir) private ReferenceCounter<IndexSearcher> getNewServiceSearcher(final Directory dir)
throws IOException { throws IOException {
if(LOG.isInfoEnabled()) if(LOG.isInfoEnabled())
LOG.info("Create new ServiceSearcher"); LOG.info("Create new ServiceSearcher");
@ -272,34 +270,58 @@ public class IndexController implements SearchComponent, IndexEventListener,
/** /**
* @see org.apache.lucene.gdata.server.registry.EntryEventListener#fireUpdateEvent(org.apache.lucene.gdata.data.ServerBaseEntry) * @see org.apache.lucene.gdata.server.registry.EntryEventListener#fireUpdateEvent(org.apache.lucene.gdata.data.ServerBaseEntry)
*/ */
public void fireUpdateEvent(ServerBaseEntry entry) { public void fireUpdateEvent(final ServerBaseEntry entry) {
createNewIndexerTask(entry, IndexAction.UPDATE); createNewIndexerTask(entry, IndexAction.UPDATE);
} }
/** /**
* @see org.apache.lucene.gdata.server.registry.EntryEventListener#fireInsertEvent(org.apache.lucene.gdata.data.ServerBaseEntry) * @see org.apache.lucene.gdata.server.registry.EntryEventListener#fireInsertEvent(org.apache.lucene.gdata.data.ServerBaseEntry)
*/ */
public void fireInsertEvent(ServerBaseEntry entry) { public void fireInsertEvent(final ServerBaseEntry entry) {
createNewIndexerTask(entry, IndexAction.INSERT); createNewIndexerTask(entry, IndexAction.INSERT);
} }
/** /**
* @see org.apache.lucene.gdata.server.registry.EntryEventListener#fireDeleteEvent(org.apache.lucene.gdata.data.ServerBaseEntry) * @see org.apache.lucene.gdata.server.registry.EntryEventListener#fireDeleteEvent(org.apache.lucene.gdata.data.ServerBaseEntry)
*/ */
public void fireDeleteEvent(ServerBaseEntry entry) { public void fireDeleteEvent(final ServerBaseEntry entry) {
createNewIndexerTask(entry, IndexAction.DELETE); createNewIndexerTask(entry, IndexAction.DELETE);
} }
// TODO add test for this method!! /**
private void createNewIndexerTask(ServerBaseEntry entry, IndexAction action) { * @see org.apache.lucene.gdata.server.registry.EntryEventListener#fireDeleteAllEntries(org.apache.lucene.gdata.data.ServerBaseFeed)
if (this.destroyed.get()) */
throw new IllegalStateException( public void fireDeleteAllEntries(final ServerBaseFeed feed) {
"IndexController has been destroyed"); createNewDeleteAllEntriesTask(feed);
if(!this.isInitialized.get()) }
throw new IllegalStateException(
"IndexController has not been initialized");
private void createNewDeleteAllEntriesTask(final ServerBaseFeed feed){
checkDestroyed();
checkInitialized();
if(LOG.isInfoEnabled())
LOG.info("Deleting all entries for feed dispatch new IndexDocumentBuilder -- "+feed.getId());
String serviceName = feed.getServiceConfig().getName();
ServiceIndex bean = this.indexerMap.get(serviceName);
if (bean == null)
throw new RuntimeException("no indexer for service " + serviceName
+ " registered");
Lock lock = bean.getLock();
lock.lock();
try{
IndexDocumentBuilder<IndexDocument> callable = new IndexFeedDeleteTask(feed.getId());
sumbitTask(callable,bean.getIndexer());
}finally{
lock.unlock();
}
}
// TODO add test for this method!!
private void createNewIndexerTask(final ServerBaseEntry entry, final IndexAction action) {
checkDestroyed();
checkInitialized();
String serviceName = entry.getServiceConfig().getName(); String serviceName = entry.getServiceConfig().getName();
if (LOG.isInfoEnabled()) if (LOG.isInfoEnabled())
LOG.info("New Indexer Task submitted - Action: " + action LOG.info("New Indexer Task submitted - Action: " + action
@ -320,15 +342,7 @@ public class IndexController implements SearchComponent, IndexEventListener,
boolean commitAfter = bean.incrementActionAndReset(schema.getCommitAfterDocuments()); boolean commitAfter = bean.incrementActionAndReset(schema.getCommitAfterDocuments());
IndexDocumentBuilder<IndexDocument> callable = new IndexDocumentBuilderTask<IndexDocument>( IndexDocumentBuilder<IndexDocument> callable = new IndexDocumentBuilderTask<IndexDocument>(
entry, bean.getSchema(), action, commitAfter,bean.getOptimize(schema.getOptimizeAfterCommit())); entry, bean.getSchema(), action, commitAfter,bean.getOptimize(schema.getOptimizeAfterCommit()));
Future<IndexDocument> task = this.taskExecutor.submit(callable); sumbitTask(callable,bean.getIndexer());
GDataIndexer indexer = bean.getIndexer();
try {
indexer.addIndexableDocumentTask(task);
} catch (InterruptedException e) {
throw new GdataIndexerException(
"Can not accept any index tasks -- interrupted. ", e);
}
} finally { } finally {
/* /*
* make sure to unlock * make sure to unlock
@ -338,15 +352,24 @@ public class IndexController implements SearchComponent, IndexEventListener,
} }
private void sumbitTask(final Callable<IndexDocument> callable, final GDataIndexer indexer){
Future<IndexDocument> task = this.taskExecutor.submit(callable);
try {
indexer.addIndexableDocumentTask(task);
} catch (InterruptedException e) {
throw new GdataIndexerException(
"Can not accept any index tasks -- interrupted. ", e);
}
}
/** /**
* @see org.apache.lucene.gdata.search.SearchComponent#getServiceSearcher(org.apache.lucene.gdata.server.registry.ProvidedService) * @see org.apache.lucene.gdata.search.SearchComponent#getServiceSearcher(org.apache.lucene.gdata.server.registry.ProvidedService)
*/ */
public GDataSearcher<String> getServiceSearcher(ProvidedService service) { public GDataSearcher<String> getServiceSearcher(final ProvidedService service) {
if (this.destroyed.get()) checkDestroyed();
throw new IllegalStateException( checkInitialized();
"IndexController has been destroyed");
/* /*
* get and increment. searcher will be decremented if GdataSearcher is * get and increment. searcher will be decremented if GdataSearcher is
* closed * closed
@ -367,10 +390,8 @@ public class IndexController implements SearchComponent, IndexEventListener,
* @see org.apache.lucene.gdata.search.SearchComponent#destroy() * @see org.apache.lucene.gdata.search.SearchComponent#destroy()
*/ */
public synchronized void destroy() { public synchronized void destroy() {
if (this.destroyed.get()) checkDestroyed();
throw new IllegalStateException( if(!this.isInitialized.get())
"IndexController has been destroyed");
if (!this.isInitialized.get())
return; return;
this.destroyed.set(true); this.destroyed.set(true);
this.isInitialized.set(false); this.isInitialized.set(false);
@ -391,7 +412,19 @@ public class IndexController implements SearchComponent, IndexEventListener,
this.indexerMap.clear(); this.indexerMap.clear();
} }
static class ServiceIndex { private void checkDestroyed(){
if (this.destroyed.get())
throw new IllegalStateException(
"IndexController has been destroyed");
}
private void checkInitialized(){
if(!this.isInitialized.get())
throw new IllegalStateException(
"IndexController has not been initialized");
}
final static class ServiceIndex {
private AtomicInteger actionCount = new AtomicInteger(0); private AtomicInteger actionCount = new AtomicInteger(0);
private AtomicInteger commitCount = new AtomicInteger(0); private AtomicInteger commitCount = new AtomicInteger(0);
@ -508,4 +541,6 @@ public class IndexController implements SearchComponent, IndexEventListener,
return false; return false;
} }
} }
} }

View File

@ -0,0 +1,139 @@
/**
* 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.search.index;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
/**
* This IndexDocumentBuilder deletes a entire feed form the index the builder is
* passed to if the feed has any entries in the search index. Each created and
* passed IndexFeedDeleteTask forces a commit.
*
* @author Simon Willnauer
*
*/
public class IndexFeedDeleteTask implements IndexDocumentBuilder<IndexDocument> {
private final String feedId;
IndexFeedDeleteTask(String feedId) {
if (feedId == null)
throw new IllegalArgumentException("feedId must not be null");
this.feedId = feedId;
}
/**
* @see org.apache.lucene.gdata.search.index.IndexDocumentBuilder#call()
*/
public IndexDocument call() throws GdataIndexerException {
return new FeedDeleteDocument(this.feedId);
}
private static class FeedDeleteDocument implements IndexDocument {
private final Term deleteTerm;
FeedDeleteDocument(String feedId) {
this.deleteTerm = new Term(FIELD_FEED_ID, feedId);
}
/**
* @see org.apache.lucene.gdata.search.index.IndexDocument#isUpdate()
*/
public boolean isUpdate() {
return false;
}
/**
* @see org.apache.lucene.gdata.search.index.IndexDocument#isDelete()
*/
public boolean isDelete() {
return true;
}
/**
* @see org.apache.lucene.gdata.search.index.IndexDocument#isInsert()
*/
public boolean isInsert() {
return false;
}
/**
* @see org.apache.lucene.gdata.search.index.IndexDocument#getWriteable()
*/
public Document getWriteable() {
return null;
}
/**
* @see org.apache.lucene.gdata.search.index.IndexDocument#getDeletealbe()
*/
public Term getDeletealbe() {
return this.deleteTerm;
}
/**
* @see org.apache.lucene.gdata.search.index.IndexDocument#commitAfter()
*/
public boolean commitAfter() {
/*
* force commit after delete a entire feed and its entries
*/
return true;
}
/**
* @see org.apache.lucene.gdata.search.index.IndexDocument#optimizeAfter()
*/
public boolean optimizeAfter() {
return false;
}
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if(obj == null)
return false;
if (obj instanceof IndexFeedDeleteTask) {
IndexFeedDeleteTask other = (IndexFeedDeleteTask) obj;
return this.feedId.equals(other.feedId);
}
return false;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return this.feedId.hashCode();
}
}

View File

@ -55,6 +55,7 @@ public class GDataSearchService extends GDataService {
/** /**
* @see org.apache.lucene.gdata.server.GDataService#getFeed(org.apache.lucene.gdata.server.GDataRequest, org.apache.lucene.gdata.server.GDataResponse) * @see org.apache.lucene.gdata.server.GDataService#getFeed(org.apache.lucene.gdata.server.GDataRequest, org.apache.lucene.gdata.server.GDataResponse)
*/ */
@SuppressWarnings("unchecked")
@Override @Override
public BaseFeed getFeed(GDataRequest request, GDataResponse response) throws ServiceException { public BaseFeed getFeed(GDataRequest request, GDataResponse response) throws ServiceException {
String translatedQuery = request.getTranslatedQuery(); String translatedQuery = request.getTranslatedQuery();
@ -85,8 +86,12 @@ public class GDataSearchService extends GDataService {
requestFeed.setStartIndex(0); requestFeed.setStartIndex(0);
requestFeed.setItemsPerPage(0); requestFeed.setItemsPerPage(0);
requestFeed.setId(request.getFeedId()); requestFeed.setId(request.getFeedId());
BaseFeed feed = null;
BaseFeed feed = this.storage.getFeed(requestFeed); try{
feed = this.storage.getFeed(requestFeed);
}catch (StorageException e) {
throw new ServiceException("Search Failed -- can not get feed, feed not stored ",e,GDataResponse.NOT_FOUND);
}
for (String entryId : result) { for (String entryId : result) {
ServerBaseEntry requestEntry = new ServerBaseEntry(); ServerBaseEntry requestEntry = new ServerBaseEntry();
requestEntry.setId(entryId); requestEntry.setId(entryId);

View File

@ -61,7 +61,7 @@ public class GDataService implements Service {
private static final String XMLMIME = "application/atom+xml"; private static final String XMLMIME = "application/atom+xml";
private final EntryEventMediator entryEventMediator; protected final EntryEventMediator entryEventMediator;
static { static {
generator = new Generator(); generator = new Generator();
generator.setName(generatorName); generator.setName(generatorName);

View File

@ -22,17 +22,19 @@ import org.apache.lucene.gdata.data.ServerBaseFeed;
import org.apache.lucene.gdata.server.GDataResponse; import org.apache.lucene.gdata.server.GDataResponse;
import org.apache.lucene.gdata.server.GDataService; import org.apache.lucene.gdata.server.GDataService;
import org.apache.lucene.gdata.server.ServiceException; import org.apache.lucene.gdata.server.ServiceException;
import org.apache.lucene.gdata.server.registry.ProvidedService;
import org.apache.lucene.gdata.storage.StorageException; import org.apache.lucene.gdata.storage.StorageException;
/** /**
* default implementation of the {@link org.apache.lucene.gdata.server.administration.AdminService} interface. * default implementation of the
* {@link org.apache.lucene.gdata.server.administration.AdminService} interface.
*
* @author Simon Willnauer * @author Simon Willnauer
* *
*/ */
public class GDataAdminService extends GDataService implements AdminService { public class GDataAdminService extends GDataService implements AdminService {
private static final Log LOG = LogFactory.getLog(GDataAdminService.class); private static final Log LOG = LogFactory.getLog(GDataAdminService.class);
/** /**
* @throws ServiceException * @throws ServiceException
*/ */
@ -41,75 +43,95 @@ public class GDataAdminService extends GDataService implements AdminService {
} }
/**
* @see org.apache.lucene.gdata.server.administration.AdminService#createFeed(org.apache.lucene.gdata.data.ServerBaseFeed,
* org.apache.lucene.gdata.data.GDataAccount)
*/
public void createFeed(final ServerBaseFeed feed, final GDataAccount account)
throws ServiceException {
if (feed == null)
throw new ServiceException("Can not create feed -- feed is null",
GDataResponse.BAD_REQUEST);
if (account == null)
throw new ServiceException(
"Can not create feed -- account is null",
GDataResponse.UNAUTHORIZED);
if (feed.getId() == null)
throw new ServiceException("Feed ID is null can not create feed",
GDataResponse.BAD_REQUEST);
if (account.getName() == null)
throw new ServiceException(
"Account name is null -- can't create feed",
GDataResponse.UNAUTHORIZED);
try {
feed.setUpdated(getCurrentDateTime());
feed.setAccount(account);
this.storage.storeFeed(feed, account.getName());
} catch (StorageException e) {
if (LOG.isInfoEnabled())
LOG.info("Can not save feed -- " + e.getMessage(), e);
throw new ServiceException("Can not save feed", e,
GDataResponse.BAD_REQUEST);
}
}
/** /**
* @see org.apache.lucene.gdata.server.administration.AdminService#createFeed(org.apache.lucene.gdata.data.ServerBaseFeed, org.apache.lucene.gdata.data.GDataAccount) * @see org.apache.lucene.gdata.server.administration.AdminService#updateFeed(org.apache.lucene.gdata.data.ServerBaseFeed,
* org.apache.lucene.gdata.data.GDataAccount)
*/ */
public void createFeed(final ServerBaseFeed feed,final GDataAccount account) throws ServiceException { public void updateFeed(ServerBaseFeed feed, GDataAccount account)
if(feed == null) throws ServiceException {
throw new ServiceException("Can not create feed -- feed is null", GDataResponse.BAD_REQUEST); if (feed == null)
if(account == null) throw new ServiceException("Can not update null feed",
throw new ServiceException("Can not create feed -- account is null", GDataResponse.UNAUTHORIZED); GDataResponse.BAD_REQUEST);
if(feed.getId() == null) if (account == null)
throw new ServiceException("Feed ID is null can not create feed", GDataResponse.BAD_REQUEST); throw new ServiceException(
if(account.getName() == null) "Can not update feed -- account is null",
throw new ServiceException("Account name is null -- can't create feed", GDataResponse.UNAUTHORIZED); GDataResponse.UNAUTHORIZED);
try { if (feed.getId() == null)
feed.setUpdated(getCurrentDateTime()); throw new ServiceException("Feed ID is null can not update feed",
feed.setAccount(account); GDataResponse.BAD_REQUEST);
this.storage.storeFeed(feed,account.getName()); if (account.getName() == null)
} catch (StorageException e) { throw new ServiceException(
if(LOG.isInfoEnabled()) "Account name is null -- can't update feed",
LOG.info("Can not save feed -- "+e.getMessage(),e); GDataResponse.UNAUTHORIZED);
throw new ServiceException("Can not save feed",e, GDataResponse.SERVER_ERROR); try {
} feed.setAccount(account);
feed.setUpdated(getCurrentDateTime());
this.storage.updateFeed(feed, account.getName());
} catch (StorageException e) {
if (LOG.isInfoEnabled())
LOG.info("Can not update feed -- " + e.getMessage(), e);
throw new ServiceException("Can not update feed", e,
GDataResponse.BAD_REQUEST);
}
} }
/**
* @see org.apache.lucene.gdata.server.administration.AdminService#updateFeed(org.apache.lucene.gdata.data.ServerBaseFeed, org.apache.lucene.gdata.data.GDataAccount)
*/
public void updateFeed(ServerBaseFeed feed, GDataAccount account) throws ServiceException {
if(feed == null)
throw new ServiceException("Can not update null feed", GDataResponse.BAD_REQUEST);
if(account == null)
throw new ServiceException("Can not update feed -- account is null", GDataResponse.UNAUTHORIZED);
if(feed.getId() == null)
throw new ServiceException("Feed ID is null can not update feed", GDataResponse.BAD_REQUEST);
if(account.getName() == null)
throw new ServiceException("Account name is null -- can't update feed", GDataResponse.UNAUTHORIZED);
try {
feed.setAccount(account);
feed.setUpdated(getCurrentDateTime());
this.storage.updateFeed(feed,account.getName());
} catch (StorageException e) {
if(LOG.isInfoEnabled())
LOG.info("Can not update feed -- "+e.getMessage(),e);
throw new ServiceException("Can not update feed",e, GDataResponse.SERVER_ERROR);
}
}
/** /**
* @see org.apache.lucene.gdata.server.administration.AdminService#deleteFeed(org.apache.lucene.gdata.data.ServerBaseFeed) * @see org.apache.lucene.gdata.server.administration.AdminService#deleteFeed(org.apache.lucene.gdata.data.ServerBaseFeed)
*/ */
public void deleteFeed(ServerBaseFeed feed) throws ServiceException { public void deleteFeed(ServerBaseFeed feed) throws ServiceException {
if(feed == null) if (feed == null)
throw new ServiceException("Can not delete null feed", GDataResponse.BAD_REQUEST); throw new ServiceException("Can not delete null feed",
if(feed.getId() == null) GDataResponse.BAD_REQUEST);
throw new ServiceException("Feed ID is null can not delete feed", GDataResponse.BAD_REQUEST); if (feed.getId() == null)
try { throw new ServiceException("Feed ID is null can not delete feed",
this.storage.deleteFeed(feed.getId()); GDataResponse.BAD_REQUEST);
} catch (StorageException e) { String serviceid = null;
if(LOG.isInfoEnabled()) try {
LOG.info("Can not delete feed -- "+e.getMessage(),e); serviceid = this.storage.getServiceForFeed(feed.getId());
throw new ServiceException("Can not delete feed",e, GDataResponse.SERVER_ERROR); this.storage.deleteFeed(feed.getId());
} } catch (StorageException e) {
if (LOG.isInfoEnabled())
LOG.info("Can not delete feed -- " + e.getMessage(), e);
throw new ServiceException("Can not delete feed", e,
GDataResponse.BAD_REQUEST);
}
ProvidedService service = this.registry.getProvidedService(serviceid);
feed.setServiceConfig(service);
this.entryEventMediator.allEntriesDeleted(feed);
} }
@ -117,14 +139,16 @@ public class GDataAdminService extends GDataService implements AdminService {
* @see org.apache.lucene.gdata.server.administration.AdminService#createAccount(org.apache.lucene.gdata.data.GDataAccount) * @see org.apache.lucene.gdata.server.administration.AdminService#createAccount(org.apache.lucene.gdata.data.GDataAccount)
*/ */
public void createAccount(GDataAccount account) throws ServiceException { public void createAccount(GDataAccount account) throws ServiceException {
if(account == null) if (account == null)
throw new ServiceException("Can not save null account", GDataResponse.BAD_REQUEST); throw new ServiceException("Can not save null account",
GDataResponse.BAD_REQUEST);
try { try {
this.storage.storeAccount(account); this.storage.storeAccount(account);
} catch (StorageException e) { } catch (StorageException e) {
if(LOG.isInfoEnabled()) if (LOG.isInfoEnabled())
LOG.info("Can not save account -- "+e.getMessage(),e); LOG.info("Can not save account -- " + e.getMessage(), e);
throw new ServiceException("Can not save account",e, GDataResponse.SERVER_ERROR); throw new ServiceException("Can not save account", e,
GDataResponse.BAD_REQUEST);
} }
} }
@ -132,14 +156,16 @@ public class GDataAdminService extends GDataService implements AdminService {
* @see org.apache.lucene.gdata.server.administration.AdminService#deleteAccount(org.apache.lucene.gdata.data.GDataAccount) * @see org.apache.lucene.gdata.server.administration.AdminService#deleteAccount(org.apache.lucene.gdata.data.GDataAccount)
*/ */
public void deleteAccount(GDataAccount account) throws ServiceException { public void deleteAccount(GDataAccount account) throws ServiceException {
if(account == null) if (account == null)
throw new ServiceException("Can not delete null account", GDataResponse.BAD_REQUEST); throw new ServiceException("Can not delete null account",
GDataResponse.BAD_REQUEST);
try { try {
this.storage.deleteAccount(account.getName()); this.storage.deleteAccount(account.getName());
} catch (StorageException e) { } catch (StorageException e) {
if(LOG.isInfoEnabled()) if (LOG.isInfoEnabled())
LOG.info("Can not save account -- "+e.getMessage(),e); LOG.info("Can not save account -- " + e.getMessage(), e);
throw new ServiceException("Can not save account",e, GDataResponse.SERVER_ERROR); throw new ServiceException("Can not save account", e,
GDataResponse.BAD_REQUEST);
} }
} }
@ -147,52 +173,59 @@ public class GDataAdminService extends GDataService implements AdminService {
* @see org.apache.lucene.gdata.server.administration.AdminService#updateAccount(org.apache.lucene.gdata.data.GDataAccount) * @see org.apache.lucene.gdata.server.administration.AdminService#updateAccount(org.apache.lucene.gdata.data.GDataAccount)
*/ */
public void updateAccount(GDataAccount account) throws ServiceException { public void updateAccount(GDataAccount account) throws ServiceException {
if(account == null) if (account == null)
throw new ServiceException("Can not update null account", GDataResponse.BAD_REQUEST); throw new ServiceException("Can not update null account",
GDataResponse.BAD_REQUEST);
try { try {
this.storage.updateAccount(account); this.storage.updateAccount(account);
} catch (StorageException e) { } catch (StorageException e) {
if(LOG.isInfoEnabled()) if (LOG.isInfoEnabled())
LOG.info("Can not save account -- "+e.getMessage(),e); LOG.info("Can not save account -- " + e.getMessage(), e);
throw new ServiceException("Can not save account",e, GDataResponse.SERVER_ERROR); throw new ServiceException("Can not save account", e,
GDataResponse.BAD_REQUEST);
} }
} }
/** /**
* @see org.apache.lucene.gdata.server.administration.AdminService#getAccount(java.lang.String) * @see org.apache.lucene.gdata.server.administration.AdminService#getAccount(java.lang.String)
*/ */
public GDataAccount getAccount(String accountName)throws ServiceException{ public GDataAccount getAccount(String accountName) throws ServiceException {
if(accountName == null) if (accountName == null)
throw new ServiceException("Can not get null account", GDataResponse.BAD_REQUEST); throw new ServiceException("Can not get null account",
GDataResponse.BAD_REQUEST);
try { try {
return this.storage.getAccount(accountName); return this.storage.getAccount(accountName);
} catch (StorageException e) { } catch (StorageException e) {
if(LOG.isInfoEnabled()) if (LOG.isInfoEnabled())
LOG.info("Can not get account -- "+e.getMessage(),e); LOG.info("Can not get account -- " + e.getMessage(), e);
throw new ServiceException("Can not get account",e, GDataResponse.SERVER_ERROR); throw new ServiceException("Can not get account", e,
GDataResponse.BAD_REQUEST);
} }
} }
/** /**
* @see org.apache.lucene.gdata.server.administration.AdminService#getFeedOwningAccount(java.lang.String) * @see org.apache.lucene.gdata.server.administration.AdminService#getFeedOwningAccount(java.lang.String)
*/ */
public GDataAccount getFeedOwningAccount(String feedId) throws ServiceException { public GDataAccount getFeedOwningAccount(String feedId)
if(feedId == null) throws ServiceException {
throw new ServiceException("Can not get account - feed id must not be null", GDataResponse.BAD_REQUEST); if (feedId == null)
throw new ServiceException(
"Can not get account - feed id must not be null",
GDataResponse.BAD_REQUEST);
try { try {
String accountName = this.storage.getAccountNameForFeedId(feedId); String accountName = this.storage.getAccountNameForFeedId(feedId);
return this.storage.getAccount(accountName); return this.storage.getAccount(accountName);
} catch (StorageException e) { } catch (StorageException e) {
if(LOG.isInfoEnabled()) if (LOG.isInfoEnabled())
LOG.info("Can not get account for feed Id -- "+e.getMessage(),e); LOG.info(
throw new ServiceException("Can not get account for the given feed id",e, GDataResponse.SERVER_ERROR); "Can not get account for feed Id -- " + e.getMessage(),
e);
throw new ServiceException(
"Can not get account for the given feed id", e,
GDataResponse.BAD_REQUEST);
} }
} }
} }

View File

@ -17,6 +17,7 @@
package org.apache.lucene.gdata.server.registry; package org.apache.lucene.gdata.server.registry;
import org.apache.lucene.gdata.data.ServerBaseEntry; import org.apache.lucene.gdata.data.ServerBaseEntry;
import org.apache.lucene.gdata.data.ServerBaseFeed;
/** /**
* The EntryEventListener interface should be implemented by any class needs to be informed about any changes on entries. * The EntryEventListener interface should be implemented by any class needs to be informed about any changes on entries.
@ -45,4 +46,10 @@ public interface EntryEventListener {
* @param entry * @param entry
*/ */
public abstract void fireDeleteEvent(ServerBaseEntry entry); public abstract void fireDeleteEvent(ServerBaseEntry entry);
/**
* will be invoked on every successful feed delete
* @param feed - the feed containing the feed id to delete all entries for
*/
public abstract void fireDeleteAllEntries(ServerBaseFeed feed);
} }

View File

@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.lucene.gdata.data.ServerBaseEntry; import org.apache.lucene.gdata.data.ServerBaseEntry;
import org.apache.lucene.gdata.data.ServerBaseFeed;
/** /**
* This class will be informed about every successful entry event and * This class will be informed about every successful entry event and
@ -40,8 +41,8 @@ public abstract class EntryEventMediator {
public abstract EntryEventMediator getEntryEventMediator(); public abstract EntryEventMediator getEntryEventMediator();
/** /**
* Registers a {@link EntryEventListener}. This listner will be fired if an * Registers a {@link EntryEventListener}. This listener will be fired if an
* entry update, insert or delete occures * entry update, insert or delete occurs
* *
* @param listener - * @param listener -
* listener to register * listener to register
@ -72,6 +73,15 @@ public abstract class EntryEventMediator {
} }
} }
/**
* @param feed - the feed to delete all entries for
*/
public void allEntriesDeleted(final ServerBaseFeed feed){
for (EntryEventListener listener : this.entryEventListener) {
listener.fireDeleteAllEntries(feed);
}
}
/** /**
* @param entry - * @param entry -
* the deleted entry * the deleted entry
@ -82,6 +92,11 @@ public abstract class EntryEventMediator {
} }
} }
/**
* checks if the listener is already registered.
* @param listner - the listener to check
* @return <code>true</code> if and only if the given listener is already registered, otherwise <code>false</code>.
*/
public boolean isListenerRegistered(final EntryEventListener listner){ public boolean isListenerRegistered(final EntryEventListener listner){
return listner!=null&&this.entryEventListener.contains(listner); return listner!=null&&this.entryEventListener.contains(listner);
} }

View File

@ -320,7 +320,6 @@ public class GDataServerRegistry extends EntryEventMediator{
ScopeVisitor.class)) ScopeVisitor.class))
this.registerScopeVisitor((ScopeVisitor) comp); this.registerScopeVisitor((ScopeVisitor) comp);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
throw new RegistryException("Can not register component -- " throw new RegistryException("Can not register component -- "
+ e.getMessage(), e); + e.getMessage(), e);
} }

View File

@ -166,6 +166,8 @@ public class DB4oController implements StorageController, ScopeVisitor {
Db4o.configure().optimizeNativeQueries(false); Db4o.configure().optimizeNativeQueries(false);
if (this.runAsServer) { if (this.runAsServer) {
this.server = Db4o.openServer(this.filePath, this.port); this.server = Db4o.openServer(this.filePath, this.port);
if(this.server == null)
throw new RuntimeException("Can't create server at confiugred destination -- "+this.filePath);
this.server.grantAccess(this.user, this.password); this.server.grantAccess(this.user, this.password);
} else { } else {
InvocationHandler handler = new ObjectServerDecorator(this.user, InvocationHandler handler = new ObjectServerDecorator(this.user,

View File

@ -46,6 +46,8 @@ import com.google.gdata.data.DateTime;
public class DB4oStorage implements Storage { public class DB4oStorage implements Storage {
private static final Log LOG = LogFactory.getLog(DB4oStorage.class); private static final Log LOG = LogFactory.getLog(DB4oStorage.class);
private static final int RENDER_ACTIVATION_DEPTH = 100;
private final ObjectContainer container; private final ObjectContainer container;
private final StorageController controller; private final StorageController controller;
@ -309,6 +311,7 @@ public class DB4oStorage implements Storage {
for (DB4oEntry entry : sublist) { for (DB4oEntry entry : sublist) {
persistentFeed.getEntries().add(clearDynamicElements(entry.getEntry())); persistentFeed.getEntries().add(clearDynamicElements(entry.getEntry()));
} }
this.container.activate(persistentFeed,RENDER_ACTIVATION_DEPTH);
return persistentFeed; return persistentFeed;
} }
@ -361,7 +364,9 @@ public class DB4oStorage implements Storage {
throw new StorageException("can not retrieve entry -- id is null"); throw new StorageException("can not retrieve entry -- id is null");
if (LOG.isInfoEnabled()) if (LOG.isInfoEnabled())
LOG.info("Retrieving entry for entryID: " + entry.getId()); LOG.info("Retrieving entry for entryID: " + entry.getId());
return clearDynamicElements(getInternalEntry(entry.getId()).getEntry()); DB4oEntry retval = getInternalEntry(entry.getId());
this.container.activate(retval.getEntry(),RENDER_ACTIVATION_DEPTH);
return clearDynamicElements(retval.getEntry());
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@ -109,4 +109,27 @@ public class IndexDocumentStub implements IndexDocument {
this.optimizeAfter = optimizeAfter; this.optimizeAfter = optimizeAfter;
} }
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public final boolean equals(Object obj) {
if(obj == null)
return false;
if(obj instanceof IndexDocumentStub){
IndexDocumentStub other = (IndexDocumentStub)obj;
return this.document.getField(IndexDocument.FIELD_ENTRY_ID).stringValue().equals(other.document.getField(IndexDocument.FIELD_ENTRY_ID).stringValue());
}
return false;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public final int hashCode() {
return this.document.getField(IndexDocument.FIELD_ENTRY_ID).stringValue().hashCode();
}
} }

View File

@ -46,7 +46,7 @@ public class TestGdataIndexer extends TestCase {
private static IndexSchema config; private static IndexSchema config;
private static String FIELD_ID = "id"; private static String FIELD_ID = IndexDocument.FIELD_ENTRY_ID;
static { static {
config = new IndexSchema(); config = new IndexSchema();
@ -244,7 +244,8 @@ public void testAddDocument() throws IOException {
Hits h = s.search(new TermQuery(delTerm)); Hits h = s.search(new TermQuery(delTerm));
assertEquals(1, h.length()); assertEquals(1, h.length());
s.close(); s.close();
String testFieldName = "someTestFieldupdate";
doc.add(new Field(testFieldName,"someText",Field.Store.YES,Field.Index.TOKENIZED));
iDoc = new IndexDocumentStub(doc,delTerm, iDoc = new IndexDocumentStub(doc,delTerm,
IndexAction.UPDATE); IndexAction.UPDATE);
/* /*
@ -261,6 +262,7 @@ public void testAddDocument() throws IOException {
s = new IndexSearcher(this.dir); s = new IndexSearcher(this.dir);
h = s.search(new TermQuery(delTerm)); h = s.search(new TermQuery(delTerm));
assertEquals(1, h.length()); assertEquals(1, h.length());
assertNotNull(h.doc(0).getField(testFieldName));
s.close(); s.close();
iDoc = new IndexDocumentStub(doc,delTerm, iDoc = new IndexDocumentStub(doc,delTerm,
@ -313,7 +315,7 @@ public void testAddDocument() throws IOException {
s.close(); s.close();
/* /*
* test insert / del without commit * test insert / del without optimize
*/ */
iDoc = new IndexDocumentStub(doc,delTerm, iDoc = new IndexDocumentStub(doc,delTerm,
IndexAction.INSERT); IndexAction.INSERT);
@ -327,8 +329,31 @@ public void testAddDocument() throws IOException {
assertEquals(0, h.length()); assertEquals(0, h.length());
s.close(); s.close();
/* /*
* test insert / update / del without commit * test insert / del / update without optimize
*/
iDoc = new IndexDocumentStub(doc,delTerm,
IndexAction.INSERT);
this.indexer.addDocument(iDoc);
iDoc = new IndexDocumentStub(doc,delTerm,
IndexAction.DELETE);
this.indexer.deleteDocument(iDoc);
iDoc = new IndexDocumentStub(doc,delTerm,
IndexAction.INSERT);
this.indexer.addDocument(iDoc);
this.indexer.commit(false);
s = new IndexSearcher(this.dir);
h = s.search(new TermQuery(delTerm));
assertEquals(1, h.length());
s.close();
/*
* test insert / update / del without optimize
*/ */
iDoc = new IndexDocumentStub(doc,delTerm, iDoc = new IndexDocumentStub(doc,delTerm,
IndexAction.INSERT); IndexAction.INSERT);
@ -345,6 +370,8 @@ public void testAddDocument() throws IOException {
assertEquals(0, h.length()); assertEquals(0, h.length());
s.close(); s.close();
iDoc = new IndexDocumentStub(doc,delTerm, iDoc = new IndexDocumentStub(doc,delTerm,
IndexAction.UPDATE); IndexAction.UPDATE);
try{ try{