mirror of https://github.com/apache/lucene.git
gdata update
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@425538 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a0288da46d
commit
5e61ac9bf1
|
@ -43,6 +43,7 @@
|
|||
<property name="junit.output.dir" location="${build.dir}/test"/>
|
||||
<property name="junit.reports" location="${build.dir}/test/reports"/>
|
||||
<property name="junit.includes" value="**/Test*.java,**/*Test.java"/>
|
||||
<property name="junit.excludes" value=""/>
|
||||
|
||||
<available
|
||||
property="javacc.present"
|
||||
|
@ -179,7 +180,7 @@
|
|||
<formatter type="xml"/>
|
||||
<formatter type="brief" usefile="false"/>
|
||||
<batchtest fork="yes" todir="${junit.output.dir}" unless="testcase">
|
||||
<fileset dir="src/test" includes="${junit.includes}"/>
|
||||
<fileset dir="src/test" includes="${junit.includes}" excludes="${junit.excludes}"/>
|
||||
</batchtest>
|
||||
<batchtest fork="yes" todir="${junit.output.dir}" if="testcase">
|
||||
<fileset dir="src/test" includes="**/${testcase}.java"/>
|
||||
|
|
|
@ -1,58 +1,84 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<project name="gdata-server" default="default">
|
||||
|
||||
<description>
|
||||
Serverside Google Data API implementation
|
||||
</description>
|
||||
|
||||
<property name="gdata.war.name" value="gdata-server"/>
|
||||
<property name="gdata.lib.dir" value="lib"/>
|
||||
|
||||
<path id="additional.dependencies">
|
||||
<pathelement location="lib/servlet-api.jar" />
|
||||
<!-- easymock version 1.2 for java 1.3 -->
|
||||
<pathelement location="lib/easymock.jar" />
|
||||
<pathelement location="lib/gdata-client-1.0.jar" />
|
||||
<pathelement location="lib/commons-logging-1.1.jar" />
|
||||
<pathelement location="lib/commons-jxpath-1.2.jar" />
|
||||
<pathelement location="lib/commons-digester-1.7.jar" />
|
||||
<pathelement location="lib/commons-beanutils.jar" />
|
||||
<pathelement location="lib/commons-collections-3.2.jar" />
|
||||
|
||||
|
||||
|
||||
|
||||
<project name="gdata-server" default="default" >
|
||||
<description>
|
||||
Serverside Google Data API implementation
|
||||
</description>
|
||||
<property name="javac.source" value="1.5" />
|
||||
<property name="javac.target" value="1.5" />
|
||||
<property name="gdata.war.name" value="gdata-server" />
|
||||
<property name="gdata.lib.dir" value="lib" />
|
||||
<property name="db4o.jar" value="db4o-5.2-java5.jar" />
|
||||
<!-- set property for third party jars -->
|
||||
<available property="db4o.jar.present" type="file" file="${gdata.lib.dir}/${db4o.jar}" value="test"/>
|
||||
<condition property="junit.excludes" value="**/TestDb4o*.java">
|
||||
<not>
|
||||
<isset property="db4o.jar.present"/>
|
||||
</not>
|
||||
</condition>
|
||||
<path id="additional.dependencies">
|
||||
<fileset dir="${gdata.lib.dir}">
|
||||
<include name="easymock.jar" />
|
||||
<include name="servlet-api.jar" />
|
||||
<include name="commons-logging-1.1.jar" />
|
||||
<include name="gdata-client-1.0.jar" />
|
||||
<include name="commons-digester-1.7.jar" />
|
||||
<include name="commons-beanutils.jar" />
|
||||
<include name="commons-collections-3.2.jar" />
|
||||
<include name="${db4o.jar}" if="db4o.jar.present" />
|
||||
</fileset>
|
||||
</path>
|
||||
|
||||
|
||||
<!-- redefine compile-core and compile-test to exclude 3rd party dependend sources -->
|
||||
<target name="compile-core" depends="init">
|
||||
<echo>Use gdata - compile-core task </echo>
|
||||
<compile srcdir="src/java" destdir="${build.dir}/classes/java">
|
||||
<classpath refid="classpath" />
|
||||
<exclude name="org/apache/lucene/gdata/storage/db4o/**" unless="db4o.jar.present" />
|
||||
</compile>
|
||||
|
||||
</target>
|
||||
|
||||
<target name="compile-test" depends="compile-core">
|
||||
<echo>Use gdata - compile-test task </echo>
|
||||
<compile srcdir="src/test" destdir="${build.dir}/classes/test">
|
||||
<classpath refid="test.classpath" />
|
||||
<exclude name="org/apache/lucene/gdata/storage/db4o/**" unless="db4o.jar.present" />
|
||||
</compile>
|
||||
<copy todir="${build.dir}/classes/test">
|
||||
<fileset dir="src/test" excludes="**/*.java" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<pathconvert property="project.classpath" targetos="unix" refid="additional.dependencies" />
|
||||
|
||||
<property name="javac.source" value="1.5"/>
|
||||
<property name="javac.target" value="1.5"/>
|
||||
<import file="../contrib-build.xml" />
|
||||
|
||||
<target name="prepare-dist" depends="jar-core">
|
||||
<echo>Prepare dist directory</echo>
|
||||
<delete dir="${dist.dir}"/>
|
||||
<mkdir dir="${dist.dir}"/>
|
||||
<delete dir="${dist.dir}" />
|
||||
<mkdir dir="${dist.dir}" />
|
||||
</target>
|
||||
<target name="war-gdata" depends="prepare-dist">
|
||||
<echo>Distributing GData War </echo>
|
||||
<war destfile="${dist.dir}/${gdata.war.name}.war"
|
||||
webxml="webroot/WEB-INF/web.xml" >
|
||||
<metainf dir="webroot/meta-inf"/>
|
||||
|
||||
|
||||
<fileset dir="webroot" excludes="WEB-INF/web.xml"/>
|
||||
<lib dir="${gdata.lib.dir}" includes="commons-logging-1.1.jar"/>
|
||||
<lib dir="${gdata.lib.dir}" includes="gdata-client-1.0.jar"/>
|
||||
<lib dir="${gdata.lib.dir}" includes="commons-digester-1.7.jar" />
|
||||
<lib dir="${gdata.lib.dir}" includes="commons-beanutils.jar" />
|
||||
<lib dir="${gdata.lib.dir}" includes="commons-collections-3.2.jar" />
|
||||
<lib dir="${build.dir}" includes="${final.name}.jar"/>
|
||||
<lib file="${lucene.jar}" />
|
||||
|
||||
<target name="war-gdata" depends="prepare-dist">
|
||||
<echo>Distributing GData War </echo>
|
||||
<war destfile="${dist.dir}/${gdata.war.name}.war" webxml="webroot/WEB-INF/web.xml">
|
||||
<metainf dir="webroot/meta-inf" />
|
||||
<fileset dir="webroot" defaultexcludes="true">
|
||||
<exclude name="meta-inf/context.xml" />
|
||||
<exclude name="meta-inf/" />
|
||||
<exclude name="WEB-INF/web.xml" />
|
||||
</fileset>
|
||||
<lib dir="${gdata.lib.dir}">
|
||||
<include name="commons-logging-1.1.jar" />
|
||||
<include name="gdata-client-1.0.jar" />
|
||||
<include name="commons-digester-1.7.jar" />
|
||||
<include name="commons-beanutils.jar" />
|
||||
<include name="commons-collections-3.2.jar" />
|
||||
<include name="${db4o.jar}" if="db4o.jar.present" />
|
||||
</lib>
|
||||
<lib dir="${build.dir}" includes="${final.name}.jar" />
|
||||
<lib file="${lucene.jar}" />
|
||||
</war>
|
||||
</target>
|
||||
|
||||
</target>
|
||||
|
||||
</project>
|
|
@ -226,9 +226,11 @@ public class GDataAccount {
|
|||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if(o == null)
|
||||
return false;
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!(o instanceof GDataAccount) || o == null)
|
||||
if (!(o instanceof GDataAccount))
|
||||
return false;
|
||||
GDataAccount toCompare = (GDataAccount) o;
|
||||
if (this.name.equals(toCompare.name))
|
||||
|
@ -301,6 +303,8 @@ public class GDataAccount {
|
|||
retVal.setRole(AccountRole.ENTRYAMINISTRATOR);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This enum respesents all account roles an account can have.
|
||||
|
|
|
@ -66,7 +66,8 @@ public class ServerBaseEntry {
|
|||
|
||||
private ProvidedService serviceConfig;
|
||||
private BaseEntry entry;
|
||||
|
||||
private static final int DEFAULTVERSION = 1;
|
||||
private int version;
|
||||
|
||||
|
||||
|
||||
|
@ -100,8 +101,8 @@ public class ServerBaseEntry {
|
|||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public ServerBaseEntry() {
|
||||
this(new Entry());
|
||||
|
||||
this.entry = new Entry();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,7 +111,7 @@ public class ServerBaseEntry {
|
|||
@SuppressWarnings("unchecked")
|
||||
public ServerBaseEntry(BaseEntry arg0) {
|
||||
this.entry = arg0;
|
||||
|
||||
this.setVersion(DEFAULTVERSION);
|
||||
}
|
||||
|
||||
|
||||
|
@ -613,6 +614,23 @@ public class ServerBaseEntry {
|
|||
public void declareExtensions(ExtensionProfile arg0) {
|
||||
this.entry.declareExtensions(arg0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the version.
|
||||
*/
|
||||
public int getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param version The version to set.
|
||||
*/
|
||||
public void setVersion(int version) {
|
||||
if(version < this.version)
|
||||
throw new IllegalArgumentException("Version must be greater than the current version -- current version: "+this.version);
|
||||
this.version = version;
|
||||
setVersionId(""+this.version);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.lucene.gdata.server.authentication.AuthenticationController;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.server.registry.ProvidedService;
|
||||
import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
|
||||
import org.apache.lucene.gdata.server.registry.ProvidedService;
|
||||
import org.apache.lucene.gdata.storage.Storage;
|
||||
import org.apache.lucene.gdata.storage.StorageController;
|
||||
|
||||
|
@ -129,6 +129,7 @@ public class GDataRequest {
|
|||
Storage storage = controller.getStorage();
|
||||
|
||||
String service = storage.getServiceForFeed(this.feedId);
|
||||
storage.close();
|
||||
/*
|
||||
* ExtensionProfile and the type is used for building the Entry /
|
||||
* Feed Instances from an inputstream or reader
|
||||
|
@ -141,8 +142,11 @@ public class GDataRequest {
|
|||
"feed is not registered or extension profile could not be created");
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
throw new GDataRequestException(
|
||||
"feed is not registered or extension profile could not be created");
|
||||
"feed is not registered or extension profile could not be created -- "
|
||||
+ e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -307,27 +311,27 @@ public class GDataRequest {
|
|||
builder.append(buildRequestIDString(false));
|
||||
builder.append("?");
|
||||
|
||||
if (builder.charAt(builder.length() - 1) != '?')
|
||||
builder.append('&');
|
||||
Enumeration parameters = this.request.getParameterNames();
|
||||
while (parameters.hasMoreElements()) {
|
||||
String element = (String) parameters.nextElement();
|
||||
String[] values = this.request.getParameterValues(element);
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
String values = this.request.getParameter(element);
|
||||
|
||||
builder.append(element).append("=");
|
||||
if (element.equals(START_INDEX_NEXT_PAGE_PARAMETER)) {
|
||||
int tempVal = DEFAULT_START_INDEX;
|
||||
try {
|
||||
tempVal = Integer.parseInt(values[i]);
|
||||
} catch (Exception e) {
|
||||
LOG.info("Can not parse StartIndex -- use defaut");
|
||||
}
|
||||
builder.append(tempVal + getItemsPerPage());
|
||||
break;
|
||||
builder.append(element).append("=");
|
||||
if (element.equals(START_INDEX_NEXT_PAGE_PARAMETER)) {
|
||||
int tempVal = DEFAULT_START_INDEX;
|
||||
try {
|
||||
tempVal = Integer.parseInt(values);
|
||||
} catch (Exception e) {
|
||||
LOG.info("Can not parse StartIndex -- use defaut");
|
||||
}
|
||||
|
||||
builder.append(values[i]);
|
||||
|
||||
builder.append(tempVal + getItemsPerPage());
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.append(values);
|
||||
|
||||
if (parameters.hasMoreElements())
|
||||
builder.append("&");
|
||||
|
||||
|
@ -339,9 +343,10 @@ public class GDataRequest {
|
|||
DEFAULT_ITEMS_PER_PAGE);
|
||||
}
|
||||
if (this.request.getParameter(START_INDEX_NEXT_PAGE_PARAMETER) == null) {
|
||||
builder.append('&');
|
||||
if (builder.charAt(builder.length() - 1) != '?')
|
||||
builder.append('&');
|
||||
builder.append(START_INDEX_NEXT_PAGE_PARAMETER).append("=");
|
||||
builder.append(DEFAULT_ITEMS_PER_PAGE + 1);
|
||||
builder.append(getItemsPerPage() + 1);
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
|
@ -352,7 +357,9 @@ public class GDataRequest {
|
|||
StringBuilder builder = new StringBuilder("http://");
|
||||
builder.append(this.request.getHeader("Host"));
|
||||
builder.append(this.request.getRequestURI());
|
||||
if (endingSlash && !this.request.getRequestURI().endsWith("/"))
|
||||
if (!endingSlash && builder.charAt(builder.length() - 1) == '/')
|
||||
builder.setLength(builder.length() - 1);
|
||||
if (endingSlash && builder.charAt(builder.length() - 1) != '/')
|
||||
builder.append("/");
|
||||
|
||||
return builder.toString();
|
||||
|
@ -454,7 +461,7 @@ public class GDataRequest {
|
|||
*/
|
||||
public boolean isFeedRequested() {
|
||||
|
||||
return (this.type.equals(GDataRequestType.GET) && (this.entryId == null
|
||||
return (this.type == GDataRequestType.GET && (this.entryId == null
|
||||
|| this.entryId.length() == 0 || (this.entryId.equals('/'))));
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ import java.util.Date;
|
|||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.lucene.gdata.server.GDataRequest.OutputFormat;
|
||||
import org.apache.lucene.gdata.utils.DateFormater;
|
||||
|
||||
|
@ -68,6 +70,7 @@ import com.google.gdata.util.common.xml.XmlWriter.Namespace;
|
|||
*
|
||||
*/
|
||||
public class GDataResponse {
|
||||
private static final Log LOG = LogFactory.getLog(GDataResponse.class);
|
||||
private int error;
|
||||
|
||||
private boolean isError = false;
|
||||
|
@ -169,7 +172,7 @@ public class GDataResponse {
|
|||
if (time != null)
|
||||
setLastModifiedHeader(time.getValue());
|
||||
XmlWriter writer = createWriter();
|
||||
|
||||
|
||||
if (this.outputFormat.equals(OutputFormat.ATOM)) {
|
||||
this.response.setContentType(XMLMIME_ATOM);
|
||||
feed.generateAtom(writer, profile);
|
||||
|
@ -177,7 +180,7 @@ public class GDataResponse {
|
|||
this.response.setContentType(XMLMIME_RSS);
|
||||
feed.generateRss(writer, profile);
|
||||
}
|
||||
|
||||
writer.close();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,6 +213,8 @@ public class GDataResponse {
|
|||
entry.generateAtom(writer, profile);
|
||||
else
|
||||
entry.generateRss(writer, profile);
|
||||
writer.close();
|
||||
|
||||
}
|
||||
|
||||
private XmlWriter createWriter() throws IOException {
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.lucene.gdata.data.ServerBaseEntry;
|
|||
import org.apache.lucene.gdata.data.ServerBaseFeed;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
|
||||
import org.apache.lucene.gdata.storage.ModificationConflictException;
|
||||
import org.apache.lucene.gdata.storage.ResourceNotFoundException;
|
||||
import org.apache.lucene.gdata.storage.Storage;
|
||||
import org.apache.lucene.gdata.storage.StorageController;
|
||||
|
@ -103,7 +104,9 @@ public class GDataService implements Service {
|
|||
ServerBaseEntry entry = buildEntry(request, response);
|
||||
entry.setFeedId(request.getFeedId());
|
||||
entry.setServiceConfig(request.getConfigurator());
|
||||
setTimeStamps(entry.getEntry());
|
||||
BaseEntry tempEntry = entry.getEntry();
|
||||
tempEntry.setPublished(getCurrentDateTime());
|
||||
tempEntry.setUpdated(getCurrentDateTime());
|
||||
BaseEntry retVal = null;
|
||||
try {
|
||||
retVal = this.storage.storeEntry(entry);
|
||||
|
@ -129,6 +132,7 @@ public class GDataService implements Service {
|
|||
entry.setServiceConfig(request.getConfigurator());
|
||||
entry.setFeedId(request.getFeedId());
|
||||
entry.setId(request.getEntryId());
|
||||
setVersionId(entry,request,response);
|
||||
if (entry.getId() == null)
|
||||
throw new ServiceException(
|
||||
"entry id is null -- can not delete null entry");
|
||||
|
@ -140,7 +144,13 @@ public class GDataService implements Service {
|
|||
"Could not delete entry", e);
|
||||
ex.setStackTrace(e.getStackTrace());
|
||||
throw ex;
|
||||
} catch (Exception e) {
|
||||
}catch (ModificationConflictException e) {
|
||||
response.setError(HttpServletResponse.SC_CONFLICT);
|
||||
ServiceException ex = new ServiceException(
|
||||
"Could not delete entry - version confilict", e);
|
||||
ex.setStackTrace(e.getStackTrace());
|
||||
throw ex;
|
||||
}catch (StorageException e) {
|
||||
response.setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
ServiceException ex = new ServiceException(
|
||||
"Could not delete entry", e);
|
||||
|
@ -160,7 +170,7 @@ public class GDataService implements Service {
|
|||
|
||||
ServerBaseEntry entry = buildEntry(request, response);
|
||||
entry.setFeedId(request.getFeedId());
|
||||
|
||||
setVersionId(entry,request,response);
|
||||
entry.setServiceConfig(request.getConfigurator());
|
||||
if (LOGGER.isInfoEnabled())
|
||||
LOGGER.info("update Entry" + entry.getId() + " for feedId: "
|
||||
|
@ -180,7 +190,11 @@ public class GDataService implements Service {
|
|||
throw new ServiceException(
|
||||
"Entry id in the entry xml does not match the requested resource");
|
||||
}
|
||||
setTimeStamps(entry.getEntry());
|
||||
BaseEntry tempEntry = entry.getEntry();
|
||||
tempEntry.setUpdated(getCurrentDateTime());
|
||||
Link selfLink = entry.getSelfLink();
|
||||
if(selfLink != null)
|
||||
entry.getLinks().remove(selfLink);
|
||||
BaseEntry retVal = null;
|
||||
try {
|
||||
retVal = this.storage.updateEntry(entry);
|
||||
|
@ -190,7 +204,13 @@ public class GDataService implements Service {
|
|||
"Could not update entry", e);
|
||||
ex.setStackTrace(e.getStackTrace());
|
||||
throw ex;
|
||||
} catch (StorageException e) {
|
||||
}catch (ModificationConflictException e) {
|
||||
response.setError(HttpServletResponse.SC_CONFLICT);
|
||||
ServiceException ex = new ServiceException(
|
||||
"Could not update entry - version confilict", e);
|
||||
ex.setStackTrace(e.getStackTrace());
|
||||
throw ex;
|
||||
}catch (StorageException e) {
|
||||
response.setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
ServiceException ex = new ServiceException(
|
||||
"Could not update entry", e);
|
||||
|
@ -261,13 +281,6 @@ public class GDataService implements Service {
|
|||
}
|
||||
}
|
||||
|
||||
private BaseEntry setTimeStamps(final BaseEntry entry) {
|
||||
if (entry.getUpdated() == null)
|
||||
entry.setUpdated(DateTime.now());
|
||||
if (entry.getPublished() == null)
|
||||
entry.setPublished(DateTime.now());
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.server.Service#getSingleEntry(org.apache.lucene.gdata.server.GDataRequest,
|
||||
|
@ -282,6 +295,8 @@ public class GDataService implements Service {
|
|||
entry.setServiceConfig(request.getConfigurator());
|
||||
entry.setFeedId(request.getFeedId());
|
||||
entry.setId(request.getEntryId());
|
||||
|
||||
|
||||
if(entry.getId() == null){
|
||||
response.setError(HttpServletResponse.SC_BAD_REQUEST);
|
||||
throw new ServiceException("entry is null can't get entry");
|
||||
|
@ -318,10 +333,10 @@ public class GDataService implements Service {
|
|||
@SuppressWarnings("unchecked")
|
||||
private void dynamicElementFeedStragey(final BaseFeed feed,
|
||||
final GDataRequest request) {
|
||||
buildDynamicFeedElements(request, feed);
|
||||
buildDynamicFeedElements(request, feed);
|
||||
List<BaseEntry> entryList = feed.getEntries();
|
||||
for (BaseEntry entry : entryList) {
|
||||
String id = request.getContextPath() + entry.getId();
|
||||
String id = new StringBuilder(request.getContextPath()).append(entry.getId()).append("/").toString();
|
||||
setSelfLink(entry, id);
|
||||
}
|
||||
|
||||
|
@ -334,7 +349,12 @@ public class GDataService implements Service {
|
|||
*/@SuppressWarnings("unchecked")
|
||||
private BaseEntry setSelfLink(final BaseEntry entry, String id) {
|
||||
Link self = buildLink(Link.Rel.SELF, XMLMIME, id);
|
||||
entry.getLinks().add(self);
|
||||
StringBuilder builder = new StringBuilder(id);
|
||||
builder.append(entry.getVersionId());
|
||||
Link edit = buildLink(Link.Rel.ENTRY_EDIT,XMLMIME,builder.toString());
|
||||
List<Link> list = entry.getLinks();
|
||||
list.add(edit);
|
||||
list.add(self);
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
@ -347,10 +367,12 @@ public class GDataService implements Service {
|
|||
feed.setItemsPerPage(request.getItemsPerPage());
|
||||
feed.setStartIndex(request.getStartIndex());
|
||||
feed.setId(request.getContextPath());
|
||||
feed.getLinks().add(
|
||||
List<Link> links = feed.getLinks();
|
||||
links.add(
|
||||
buildLink(Link.Rel.SELF, Link.Type.ATOM, request.getSelfId()));
|
||||
feed.getLinks().add(
|
||||
links.add(
|
||||
buildLink(Link.Rel.NEXT, XMLMIME, request.getNextId()));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -394,5 +416,23 @@ public class GDataService implements Service {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
private ServerBaseEntry setVersionId(final ServerBaseEntry entry, final GDataRequest request, final GDataResponse response)throws ServiceException{
|
||||
try{
|
||||
entry.setVersion(Integer.parseInt(request.getEntryVersion()));
|
||||
return entry;
|
||||
}catch (Exception e) {
|
||||
LOGGER.error("Can not parse entry version -- version is not an integer -- versionid: "+request.getEntryVersion(),e);
|
||||
response.setError(HttpServletResponse.SC_BAD_REQUEST);
|
||||
throw new ServiceException("Can not parse entry version -- version is not an integer -- versionid: "+request.getEntryVersion(),e);
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* provide current time to set as published / updated values
|
||||
* always use servertime to prevent client / server time lag
|
||||
* Timezoneshift is 0
|
||||
*/
|
||||
protected DateTime getCurrentDateTime(){
|
||||
return new DateTime(System.currentTimeMillis(),0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.Reader;
|
|||
|
||||
import org.apache.commons.digester.Digester;
|
||||
import org.apache.lucene.gdata.data.GDataAccount;
|
||||
import org.apache.lucene.gdata.utils.SimpleSaxErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
|
@ -42,9 +43,12 @@ public class AccountBuilder {
|
|||
SAXException {
|
||||
if (reader == null)
|
||||
throw new IllegalArgumentException("Reader must not be null");
|
||||
String schemaFile = AccountBuilder.class.getResource("/gdata-account.xsd").getFile();
|
||||
GDataAccount account = null;
|
||||
Digester digester = new Digester();
|
||||
digester.setValidating(false);
|
||||
digester.setValidating(true);
|
||||
digester.setErrorHandler(new SimpleSaxErrorHandler());
|
||||
digester.setSchema(schemaFile);
|
||||
digester.addObjectCreate("account", GDataAccount.class);
|
||||
digester.addBeanPropertySetter("account/account-name", "name");
|
||||
digester.addBeanPropertySetter("account/password", "password");
|
||||
|
@ -55,8 +59,12 @@ public class AccountBuilder {
|
|||
"authorMail");
|
||||
digester.addBeanPropertySetter("account/account-owner/url",
|
||||
"authorLink");
|
||||
|
||||
account = (GDataAccount) digester.parse(reader);
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ public class GDataAdminService extends GDataService implements AdminService {
|
|||
if(account.getName() == null)
|
||||
throw new ServiceException("Account name is null -- can't create feed");
|
||||
try {
|
||||
feed.setUpdated(getCurrentDateTime());
|
||||
feed.setAccount(account);
|
||||
this.storage.storeFeed(feed,account.getName());
|
||||
} catch (StorageException e) {
|
||||
|
@ -81,6 +82,7 @@ public class GDataAdminService extends GDataService implements AdminService {
|
|||
throw new ServiceException("Account name is null -- can't update feed");
|
||||
try {
|
||||
feed.setAccount(account);
|
||||
feed.setUpdated(getCurrentDateTime());
|
||||
this.storage.updateFeed(feed,account.getName());
|
||||
} catch (StorageException e) {
|
||||
if(LOG.isInfoEnabled())
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.lucene.gdata.data.GDataAccount;
|
|||
import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
|
||||
import org.apache.lucene.gdata.server.registry.Component;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.server.registry.configuration.Requiered;
|
||||
|
||||
import sun.misc.BASE64Decoder;
|
||||
import sun.misc.BASE64Encoder;
|
||||
|
@ -81,7 +82,6 @@ public class BlowfishAuthenticationController implements
|
|||
|
||||
private Cipher enCrypt;
|
||||
|
||||
// TODO make this configurable
|
||||
private int minuteOffset = 30;
|
||||
|
||||
private long milisecondOffset;
|
||||
|
@ -92,8 +92,8 @@ public class BlowfishAuthenticationController implements
|
|||
|
||||
private ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
// TODO make this configurable
|
||||
private String key = "myTestKey";
|
||||
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.server.authentication.AuthenticationController#initialize()
|
||||
|
@ -236,7 +236,8 @@ public class BlowfishAuthenticationController implements
|
|||
/**
|
||||
* @return Returns the minuteOffset.
|
||||
*/
|
||||
public int getMinuteOffset() {
|
||||
@Requiered
|
||||
public int getLoginTimeout() {
|
||||
return this.minuteOffset;
|
||||
}
|
||||
|
||||
|
@ -244,7 +245,8 @@ public class BlowfishAuthenticationController implements
|
|||
* @param minuteOffset
|
||||
* The minuteOffset to set.
|
||||
*/
|
||||
public void setMinuteOffset(int minuteOffset) {
|
||||
@Requiered
|
||||
public void setLoginTimeout(int minuteOffset) {
|
||||
this.minuteOffset = minuteOffset;
|
||||
calculateTimeOffset();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
* Copyright 2004 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.lucene.gdata.server.registry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletRequestEvent;
|
||||
import javax.servlet.ServletRequestListener;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.lucene.gdata.server.registry.Scope.ScopeType;
|
||||
|
||||
/**
|
||||
* This <tt>ServletRequestListener</tt> is used by the registry to notify
|
||||
* registered {@link org.apache.lucene.gdata.server.registry.ScopeVisitor}
|
||||
* implementations when a request is initialized e.g destroyed.
|
||||
*
|
||||
*
|
||||
* @see org.apache.lucene.gdata.server.registry.ScopeVisitable
|
||||
* @see javax.servlet.ServletRequestListener
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
@Scope(scope = ScopeType.REQUEST)
|
||||
public class GDataRequestListener implements ServletRequestListener,
|
||||
ScopeVisitable {
|
||||
private final GDataServerRegistry registry;
|
||||
|
||||
private final List<ScopeVisitor> visitors = new ArrayList<ScopeVisitor>(5);
|
||||
|
||||
private static final Log LOG = LogFactory
|
||||
.getLog(GDataRequestListener.class);
|
||||
|
||||
/**
|
||||
* @throws RegistryException
|
||||
*
|
||||
*/
|
||||
public GDataRequestListener() throws RegistryException {
|
||||
this.registry = GDataServerRegistry.getRegistry();
|
||||
this.registry.registerScopeVisitable(this);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.ServletRequestListener#requestDestroyed(javax.servlet.ServletRequestEvent)
|
||||
*/
|
||||
public void requestDestroyed(ServletRequestEvent arg0) {
|
||||
for (ScopeVisitor visitor : this.visitors) {
|
||||
visitor.visiteDestroy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.servlet.ServletRequestListener#requestInitialized(javax.servlet.ServletRequestEvent)
|
||||
*/
|
||||
public void requestInitialized(ServletRequestEvent arg0) {
|
||||
for (ScopeVisitor visitor : this.visitors) {
|
||||
visitor.visiteInitialize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.server.registry.ScopeVisitable#accept(org.apache.lucene.gdata.server.registry.ScopeVisitor)
|
||||
*/
|
||||
public void accept(ScopeVisitor visitor) {
|
||||
|
||||
if (!this.visitors.contains(visitor) && visitor != null) {
|
||||
this.visitors.add(visitor);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("visitor added -- " + visitor.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -15,11 +15,16 @@
|
|||
*/
|
||||
package org.apache.lucene.gdata.server.registry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.lucene.gdata.server.registry.configuration.ComponentConfiguration;
|
||||
import org.apache.lucene.gdata.server.registry.configuration.PropertyInjector;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -41,7 +46,9 @@ import org.apache.commons.logging.LogFactory;
|
|||
* occures the server will not start up. To cause of the exception or error will
|
||||
* be logged to the standart server output.
|
||||
* </p>
|
||||
* <p>The GDataServerRegistry is a Singleton</p>
|
||||
* <p>
|
||||
* The GDataServerRegistry is a Singleton
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Simon Willnauer
|
||||
|
@ -53,10 +60,18 @@ public class GDataServerRegistry {
|
|||
private static final Log LOGGER = LogFactory
|
||||
.getLog(GDataServerRegistry.class);
|
||||
|
||||
private ScopeVisitable requestVisitable;
|
||||
|
||||
private ScopeVisitable sessionVisitable;
|
||||
//not available yet
|
||||
private ScopeVisitable contextVisitable;
|
||||
|
||||
private List<ScopeVisitor> visitorBuffer = new ArrayList<ScopeVisitor>(5);
|
||||
|
||||
private final Map<String, ProvidedService> serviceTypeMap = new HashMap<String, ProvidedService>();
|
||||
|
||||
private final Map<ComponentType, ComponentBean> componentMap = new HashMap<ComponentType, ComponentBean>(
|
||||
10);
|
||||
ComponentType.values().length);
|
||||
|
||||
private GDataServerRegistry() {
|
||||
// private - singleton
|
||||
|
@ -85,6 +100,72 @@ public class GDataServerRegistry {
|
|||
this.serviceTypeMap.put(configurator.getName(), configurator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param visitor -
|
||||
* the visitor to register
|
||||
* @throws RegistryException
|
||||
*/
|
||||
public synchronized void registerScopeVisitor(final ScopeVisitor visitor)
|
||||
throws RegistryException {
|
||||
if (visitor == null)
|
||||
throw new IllegalArgumentException("visitor must not be null");
|
||||
Scope scope = visitor.getClass().getAnnotation(Scope.class);
|
||||
if (scope == null)
|
||||
throw new RegistryException("Visitor has not Scope");
|
||||
if (LOGGER.isInfoEnabled())
|
||||
LOGGER.info("Register scope visitor -- " + visitor.getClass());
|
||||
if (scope.scope().equals(Scope.ScopeType.REQUEST)
|
||||
&& this.requestVisitable != null)
|
||||
this.requestVisitable.accept(visitor);
|
||||
else if (scope.scope() == Scope.ScopeType.SESSION
|
||||
&& this.sessionVisitable != null)
|
||||
this.sessionVisitable.accept(visitor);
|
||||
else if (scope.scope() == Scope.ScopeType.CONTEXT
|
||||
&& this.contextVisitable != null)
|
||||
this.sessionVisitable.accept(visitor);
|
||||
else if (!this.visitorBuffer.contains(visitor))
|
||||
this.visitorBuffer.add(visitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param visitable -
|
||||
* the instance to register
|
||||
* @throws RegistryException
|
||||
* @see ScopeVisitable
|
||||
*/
|
||||
public synchronized void registerScopeVisitable(
|
||||
final ScopeVisitable visitable) throws RegistryException {
|
||||
if (visitable == null)
|
||||
throw new IllegalArgumentException("visitable must not be null");
|
||||
|
||||
Scope scope = visitable.getClass().getAnnotation(Scope.class);
|
||||
if (scope == null)
|
||||
throw new RegistryException("Visitable has not Scope");
|
||||
if (LOGGER.isInfoEnabled())
|
||||
LOGGER.info("Register scope visitable -- " + visitable.getClass());
|
||||
if (scope.scope() == Scope.ScopeType.REQUEST
|
||||
&& this.requestVisitable == null)
|
||||
this.requestVisitable = visitable;
|
||||
else if (scope.scope() == Scope.ScopeType.SESSION
|
||||
&& this.sessionVisitable == null)
|
||||
this.sessionVisitable = visitable;
|
||||
else if (scope.scope() == Scope.ScopeType.CONTEXT
|
||||
&& this.contextVisitable == null)
|
||||
this.sessionVisitable = visitable;
|
||||
|
||||
if (!this.visitorBuffer.isEmpty()) {
|
||||
|
||||
List<ScopeVisitor> tempList = this.visitorBuffer;
|
||||
this.visitorBuffer = new ArrayList<ScopeVisitor>(5);
|
||||
for (ScopeVisitor visitor : tempList) {
|
||||
registerScopeVisitor(visitor);
|
||||
}
|
||||
tempList.clear();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the {@link ProvidedServiceConfig} by the given service name.
|
||||
*
|
||||
|
@ -100,6 +181,10 @@ public class GDataServerRegistry {
|
|||
}
|
||||
|
||||
protected void flushRegistry() {
|
||||
Collection<ProvidedService> services = this.serviceTypeMap.values();
|
||||
for (ProvidedService service : services) {
|
||||
service.destroy();
|
||||
}
|
||||
this.serviceTypeMap.clear();
|
||||
this.componentMap.clear();
|
||||
}
|
||||
|
@ -122,6 +207,7 @@ public class GDataServerRegistry {
|
|||
for (ComponentBean component : this.componentMap.values()) {
|
||||
component.getObject().destroy();
|
||||
}
|
||||
|
||||
flushRegistry();
|
||||
|
||||
}
|
||||
|
@ -157,23 +243,51 @@ public class GDataServerRegistry {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param <E>
|
||||
* @param componentClass
|
||||
* @throws RegistryException
|
||||
* All registered {@link ServerComponent} registered via this method are
|
||||
* available via the
|
||||
* {@link GDataServerRegistry#lookup(Class, ComponentType)} method. For each
|
||||
* {@link ComponentType} there will be one single instance registered in the
|
||||
* registry.
|
||||
* <p>
|
||||
* Eventually this method invokes the initialize method of the
|
||||
* ServerComponent interface to prepare the component to be available via
|
||||
* the lookup service
|
||||
* </p>
|
||||
*
|
||||
* @param <E> -
|
||||
* The interface of the component to register
|
||||
* @param componentClass -
|
||||
* a implementation of a ServerComponent interface to register in
|
||||
* the registry
|
||||
* @param configuration -
|
||||
* the component configuration {@link ComponentConfiguration}
|
||||
* @throws RegistryException -
|
||||
* if the provided class does not implement the
|
||||
* {@link ServerComponent} interface, if the mandatory
|
||||
* annotations not visible at runtime or not set, if the super
|
||||
* type provided by the {@link ComponentType} for the class to
|
||||
* register is not a super type of the class or if the
|
||||
* invokation of the {@link ServerComponent#initialize()} method
|
||||
* throws an exception.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends ServerComponent> void registerComponent(final Class<E> componentClass)
|
||||
public <E extends ServerComponent> void registerComponent(
|
||||
final Class<E> componentClass,
|
||||
final ComponentConfiguration configuration)
|
||||
throws RegistryException {
|
||||
|
||||
|
||||
if (componentClass == null)
|
||||
throw new IllegalArgumentException(
|
||||
"component class must not be null");
|
||||
|
||||
if(!checkImplementsServerComponent(componentClass))
|
||||
throw new RegistryException("can not register component. the given class does not implement ServerComponent interface -- "+componentClass.getName());
|
||||
|
||||
if (!checkSuperType(componentClass, ServerComponent.class))
|
||||
throw new RegistryException(
|
||||
"can not register component. the given class does not implement ServerComponent interface -- "
|
||||
+ componentClass.getName());
|
||||
try {
|
||||
|
||||
Component annotation = componentClass.getAnnotation(Component.class);
|
||||
Component annotation = componentClass
|
||||
.getAnnotation(Component.class);
|
||||
if (annotation == null)
|
||||
throw new RegistryException(
|
||||
"can not register component. the given class is not a component -- "
|
||||
|
@ -189,49 +303,53 @@ public class GDataServerRegistry {
|
|||
+ superType.getName() + "> is not a super type of <"
|
||||
+ componentClass + ">");
|
||||
ServerComponent comp = componentClass.newInstance();
|
||||
if (configuration == null) {
|
||||
if (LOGGER.isInfoEnabled())
|
||||
LOGGER.info("no configuration for ComponentType: "
|
||||
+ type.name());
|
||||
} else
|
||||
configureComponent(comp, type, configuration);
|
||||
comp.initialize();
|
||||
ComponentBean bean = new ComponentBean(comp, superType);
|
||||
|
||||
this.componentMap.put(type, bean);
|
||||
|
||||
this.componentMap.put(type, bean);
|
||||
if (checkSuperType(componentClass, ScopeVisitor.class))
|
||||
this.registerScopeVisitor((ScopeVisitor) comp);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RegistryException("Can not register component -- "
|
||||
+ e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean checkImplementsServerComponent(Class type){
|
||||
if(type == null)
|
||||
return false;
|
||||
if(type.equals(Object.class))
|
||||
return false;
|
||||
if(type.equals(ServerComponent.class))
|
||||
return true;
|
||||
Class[] compInterfaces = type.getInterfaces();
|
||||
for (int i = 0; i < compInterfaces.length; i++) {
|
||||
if(checkImplementsServerComponent(compInterfaces[i]))
|
||||
return true;
|
||||
}
|
||||
return checkImplementsServerComponent(type.getSuperclass());
|
||||
|
||||
|
||||
/*
|
||||
* Injects the configured properties located in the configuration into the
|
||||
* given server component
|
||||
*/
|
||||
private void configureComponent(final ServerComponent component,
|
||||
final ComponentType type, final ComponentConfiguration configuration) {
|
||||
PropertyInjector injector = new PropertyInjector();
|
||||
injector.setTargetObject(component);
|
||||
injector.injectProperties(configuration);
|
||||
}
|
||||
|
||||
private static boolean checkSuperType(Class type, Class consideredSuperType) {
|
||||
|
||||
if (type == null)
|
||||
return false;
|
||||
if (type.equals(Object.class))
|
||||
return false;
|
||||
if (type.equals(consideredSuperType))
|
||||
return true;
|
||||
Class[] interfaces = type.getInterfaces();
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
if (interfaces[i].equals(consideredSuperType))
|
||||
if (checkSuperType(interfaces[i], consideredSuperType))
|
||||
return true;
|
||||
}
|
||||
return checkSuperType(type.getSuperclass(), consideredSuperType);
|
||||
}
|
||||
|
||||
private class ComponentBean {
|
||||
private static class ComponentBean {
|
||||
private final Class superType;
|
||||
|
||||
private final ServerComponent object;
|
||||
|
|
|
@ -45,4 +45,9 @@ public interface ProvidedService {
|
|||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* releases all dependencies and resources
|
||||
*/
|
||||
public abstract void destroy();
|
||||
|
||||
}
|
|
@ -15,6 +15,14 @@
|
|||
*/
|
||||
package org.apache.lucene.gdata.server.registry;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.lucene.gdata.utils.Pool;
|
||||
import org.apache.lucene.gdata.utils.PoolObjectFactory;
|
||||
import org.apache.lucene.gdata.utils.SimpleObjectPool;
|
||||
|
||||
import com.google.gdata.data.ExtensionProfile;
|
||||
|
||||
/**
|
||||
|
@ -22,11 +30,40 @@ import com.google.gdata.data.ExtensionProfile;
|
|||
* {@link org.apache.lucene.gdata.server.registry.ProvidedService} to be used
|
||||
* inside the
|
||||
* {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry}
|
||||
* <p>
|
||||
* ExtensionProfiles are used to generate and parse xml by the gdata api. For
|
||||
* that case all methodes are synchronized. This will slow down the application
|
||||
* when performing lots of xml generation concurrently. For that case the
|
||||
* extensionProfile for a specific service will be pooled and reused.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public class ProvidedServiceConfig implements ProvidedService {
|
||||
@Scope(scope = Scope.ScopeType.REQUEST)
|
||||
public class ProvidedServiceConfig implements ProvidedService, ScopeVisitor {
|
||||
private final static Log LOG = LogFactory
|
||||
.getLog(ProvidedServiceConfig.class);
|
||||
|
||||
private static final int DEFAULT_POOL_SIZE = 5;
|
||||
|
||||
/*
|
||||
* To ensure a extensionprofile instance will not be shared within multiple
|
||||
* threads each thread requesting a config will have one instance for the
|
||||
* entire request.
|
||||
*/
|
||||
private final ThreadLocal<ExtensionProfile> extProfThreadLocal = new ThreadLocal<ExtensionProfile>();
|
||||
|
||||
/*
|
||||
* ExtensionProfiles are used to generate and parse xml by the gdata api.
|
||||
* For that case all methodes are synchronized. This will slow down the
|
||||
* application when performing lots of xml generation concurrently. for that
|
||||
* case the extensionProfile for a specific service will be pooled and
|
||||
* reused.
|
||||
*/
|
||||
private Pool<ExtensionProfile> profilPool;
|
||||
|
||||
private String serviceName;
|
||||
|
||||
private Class entryType;
|
||||
|
@ -35,21 +72,35 @@ public class ProvidedServiceConfig implements ProvidedService {
|
|||
|
||||
private ExtensionProfile extensionProfile;
|
||||
|
||||
|
||||
ProvidedServiceConfig(ExtensionProfile profile, Class feedType,
|
||||
Class entryType, String serviceName) {
|
||||
this.extensionProfile = profile;
|
||||
this.feedType = feedType;
|
||||
this.entryType = entryType;
|
||||
this.serviceName = serviceName;
|
||||
private int poolSize = DEFAULT_POOL_SIZE;
|
||||
|
||||
/**
|
||||
* @return Returns the poolSize.
|
||||
*/
|
||||
public int getPoolSize() {
|
||||
return this.poolSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor to instanciate via reflection
|
||||
* @param poolSize
|
||||
* The poolSize to set.
|
||||
*/
|
||||
public void setPoolSize(int poolSize) {
|
||||
|
||||
this.poolSize = poolSize >= DEFAULT_POOL_SIZE ? poolSize
|
||||
: DEFAULT_POOL_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor to instanciate via reflection
|
||||
*/
|
||||
public ProvidedServiceConfig() {
|
||||
//
|
||||
try {
|
||||
GDataServerRegistry.getRegistry().registerScopeVisitor(this);
|
||||
} catch (RegistryException e) {
|
||||
throw new RuntimeException("Can not register ScopeVisitor -- "
|
||||
+ e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,20 +122,44 @@ public class ProvidedServiceConfig implements ProvidedService {
|
|||
* @see org.apache.lucene.gdata.server.registry.ProvidedService#getExtensionProfile()
|
||||
*/
|
||||
public ExtensionProfile getExtensionProfile() {
|
||||
return this.extensionProfile;
|
||||
ExtensionProfile ext = this.extProfThreadLocal.get();
|
||||
if (ext != null) {
|
||||
return ext;
|
||||
}
|
||||
if (this.profilPool == null)
|
||||
createProfilePool();
|
||||
ext = this.profilPool.aquire();
|
||||
this.extProfThreadLocal.set(ext);
|
||||
return ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extensionProfil -
|
||||
* the extensionprofile for this feed configuration
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setExtensionProfile(ExtensionProfile extensionProfil) {
|
||||
if (extensionProfil == null)
|
||||
throw new IllegalArgumentException(
|
||||
"ExtensionProfile must not be null");
|
||||
if (this.extensionProfile != null)
|
||||
return;
|
||||
this.extensionProfile = extensionProfil;
|
||||
|
||||
}
|
||||
|
||||
private void createProfilePool() {
|
||||
if (LOG.isInfoEnabled())
|
||||
LOG.info("Create ExtensionProfile pool with poolsize:"
|
||||
+ this.poolSize + " for service " + this.serviceName);
|
||||
this.profilPool = new SimpleObjectPool<ExtensionProfile>(this.poolSize,
|
||||
new ExtensionProfileFactory<ExtensionProfile>(
|
||||
this.extensionProfile.getClass()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*TODO add comment
|
||||
* TODO add comment
|
||||
*
|
||||
* @param <E>
|
||||
* @param extensionProfileClass
|
||||
* @throws InstantiationException
|
||||
|
@ -97,7 +172,8 @@ public class ProvidedServiceConfig implements ProvidedService {
|
|||
throw new IllegalArgumentException(
|
||||
"ExtensionProfile class must not be null");
|
||||
|
||||
this.extensionProfile = extensionProfileClass.newInstance();
|
||||
setExtensionProfile(extensionProfileClass.newInstance());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,7 +182,7 @@ public class ProvidedServiceConfig implements ProvidedService {
|
|||
public Class getEntryType() {
|
||||
return this.entryType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param entryType
|
||||
*/
|
||||
|
@ -128,4 +204,95 @@ public class ProvidedServiceConfig implements ProvidedService {
|
|||
this.serviceName = serviceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.server.registry.ProvidedService#destroy()
|
||||
*/
|
||||
public void destroy() {
|
||||
if (this.profilPool != null)
|
||||
this.profilPool.destroy();
|
||||
if (LOG.isInfoEnabled())
|
||||
LOG.info("Destroy Service " + this.serviceName
|
||||
+ " -- release all resources");
|
||||
this.feedType = null;
|
||||
this.entryType = null;
|
||||
this.extensionProfile = null;
|
||||
}
|
||||
|
||||
private static class ExtensionProfileFactory<Type extends ExtensionProfile>
|
||||
implements PoolObjectFactory<Type> {
|
||||
private final Class<? extends ExtensionProfile> clazz;
|
||||
|
||||
private final Constructor<? extends ExtensionProfile> constructor;
|
||||
|
||||
private static final Object[] constArray = new Object[0];
|
||||
|
||||
ExtensionProfileFactory(Class<? extends ExtensionProfile> clazz) {
|
||||
this.clazz = clazz;
|
||||
try {
|
||||
this.constructor = clazz.getConstructor(new Class[0]);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(
|
||||
"The given class has no defaul constructor -- can not use as a ExtensionProfile -- "
|
||||
+ this.clazz.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.utils.PoolObjectFactory#getInstance()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Type getInstance() {
|
||||
|
||||
try {
|
||||
return (Type) this.constructor.newInstance(constArray);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"Can not instanciate new ExtensionProfile -- ", e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type -
|
||||
* the ExtensionProfile to destroy
|
||||
* @see org.apache.lucene.gdata.utils.PoolObjectFactory#destroyInstance(Object)
|
||||
*/
|
||||
public void destroyInstance(Type type) {
|
||||
//
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.server.registry.ScopeVisitor#visiteInitialize()
|
||||
*/
|
||||
public void visiteInitialize() {
|
||||
if(this.profilPool == null)
|
||||
createProfilePool();
|
||||
/*
|
||||
* don't set a extension profile for each thread. The current thread
|
||||
* might use another service and does not need the extensionprofile of
|
||||
* this service
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.server.registry.ScopeVisitor#visiteDestroy()
|
||||
*/
|
||||
public void visiteDestroy() {
|
||||
/*
|
||||
* Check every thread after request destroyed to release all profiles to
|
||||
* the pool
|
||||
*/
|
||||
ExtensionProfile ext = this.extProfThreadLocal.get();
|
||||
if (ext == null) {
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("ThreadLocal owns no ExtensionProfile in requestDestroy for service "
|
||||
+ this.serviceName);
|
||||
return;
|
||||
}
|
||||
this.extProfThreadLocal.set(null);
|
||||
this.profilPool.release(ext);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ package org.apache.lucene.gdata.server.registry;
|
|||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.digester.Digester;
|
||||
import org.apache.lucene.gdata.server.registry.configuration.ComponentConfiguration;
|
||||
import org.apache.lucene.gdata.utils.SimpleSaxErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
|
@ -49,11 +51,14 @@ class RegistryBuilder {
|
|||
|
||||
private static void buildFromConfiguration(Digester digester,
|
||||
GDataServerRegistry registry) throws IOException, SAXException {
|
||||
|
||||
digester.setValidating(false);
|
||||
String schemaFile = RegistryBuilder.class.getResource("/gdata-config.xsd").getFile();
|
||||
digester.setValidating(true);
|
||||
digester.setSchema(schemaFile);
|
||||
digester.setErrorHandler(new SimpleSaxErrorHandler());
|
||||
digester.push(registry);
|
||||
digester.addCallMethod("gdata/server-components/component",
|
||||
"registerComponent", 0, new Class[] { Class.class });
|
||||
/*
|
||||
* register services
|
||||
*/
|
||||
digester.addObjectCreate("gdata/service", ProvidedServiceConfig.class);
|
||||
digester.addSetProperties("gdata/service");
|
||||
digester.addSetNext("gdata/service", "registerService");
|
||||
|
@ -61,10 +66,22 @@ class RegistryBuilder {
|
|||
digester.addBeanPropertySetter("gdata/service/entry-class", "entryType");
|
||||
digester.addBeanPropertySetter("gdata/service/extension-profile",
|
||||
"extensionProfileClass");
|
||||
|
||||
/*
|
||||
* load components and configurations
|
||||
*/
|
||||
digester.addCallMethod("gdata/server-components/component",
|
||||
"registerComponent", 2, new Class[] { Class.class , ComponentConfiguration.class});
|
||||
digester.addCallParam("gdata/server-components/component/class",0);
|
||||
digester.addObjectCreate("gdata/server-components/component/configuration",ComponentConfiguration.class);
|
||||
digester.addCallMethod("gdata/server-components/component/configuration/property","set",2,new Class[]{String.class,String.class});
|
||||
digester.addCallParam("gdata/server-components/component/configuration/property",0,"name");
|
||||
digester.addCallParam("gdata/server-components/component/configuration/property",1);
|
||||
digester.addCallParam("gdata/server-components/component/configuration",1,0);
|
||||
digester.parse(RegistryBuilder.class
|
||||
.getResourceAsStream("/gdata-config.xml"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* Copyright 2004 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.lucene.gdata.server.registry;
|
||||
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* The Scope annotation is used in
|
||||
* {@link org.apache.lucene.gdata.server.registry.ScopeVisitable} and
|
||||
* {@link org.apache.lucene.gdata.server.registry.ScopeVisitor} implementations
|
||||
* to indicate which scope should be visited.
|
||||
*
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
@Target( { TYPE })
|
||||
@Retention(value = RUNTIME)
|
||||
public @interface Scope {
|
||||
/**
|
||||
* @return - the scope type the class was annotated with
|
||||
*/
|
||||
ScopeType scope();
|
||||
|
||||
/**
|
||||
* Defines a Scope for {@link Scope} annotations
|
||||
*
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public static enum ScopeType {
|
||||
/**
|
||||
* Request scope
|
||||
*/
|
||||
REQUEST,
|
||||
/**
|
||||
* Session scope
|
||||
*/
|
||||
SESSION,
|
||||
/**
|
||||
* Context scope
|
||||
*/
|
||||
CONTEXT
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* Copyright 2004 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.lucene.gdata.server.registry;
|
||||
|
||||
/**
|
||||
* Implementation of this interface accept
|
||||
* {@link org.apache.lucene.gdata.server.registry.ScopeVisitor} objects and call
|
||||
* their methods on the desired action.
|
||||
*
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public interface ScopeVisitable {
|
||||
/**
|
||||
* @param visitor -
|
||||
* the visitor to accept
|
||||
*/
|
||||
public abstract void accept(ScopeVisitor visitor);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* <code>ScopeVisitor</code> is used to implement the <code>Visitor</code>
|
||||
* pattern in GDATAServer. An object of this interface can be passed to a
|
||||
* <code>ScopeVistable</code> which will then call its methods. <br/>
|
||||
* {@link org.apache.lucene.gdata.server.registry.Component} Classes registered
|
||||
* in the {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry}
|
||||
* will be added to the Visitableimplementation automatically. Please refer to
|
||||
* the <i>Gang of Four </i> book of Design Patterns for more details on the
|
||||
* <code>Visitor</code> pattern.
|
||||
* </p>
|
||||
* <p>
|
||||
* A scope can be Session, Request or Context if one of the ScopeVisitors for
|
||||
* the desired scope is available by the registry.
|
||||
* </p>
|
||||
* <p>
|
||||
* This <a href="http://www.patterndepot.com/put/8/JavaPatterns.htm">site </a>
|
||||
* has further discussion on design patterns and links to the GOF book. This <a
|
||||
* href="http://www.patterndepot.com/put/8/visitor.pdf">link </a> describes the
|
||||
* Visitor pattern in detail.
|
||||
* </p>
|
||||
*
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public interface ScopeVisitor {
|
||||
/**
|
||||
* Visites the initialization of the scope
|
||||
*/
|
||||
public abstract void visiteInitialize();
|
||||
|
||||
/**
|
||||
* Visites the destory of the scope
|
||||
*
|
||||
*/
|
||||
public abstract void visiteDestroy();
|
||||
}
|
|
@ -60,7 +60,7 @@ public abstract class AbstractAccountHandler extends RequestAuthenticator
|
|||
@SuppressWarnings("unused")
|
||||
public void processRequest(HttpServletRequest request,
|
||||
HttpServletResponse response) throws ServletException, IOException {
|
||||
|
||||
try{
|
||||
this.authenticated = authenticateAccount(request,
|
||||
AccountRole.USERADMINISTRATOR);
|
||||
|
||||
|
@ -92,6 +92,10 @@ public abstract class AbstractAccountHandler extends RequestAuthenticator
|
|||
setError(HttpServletResponse.SC_UNAUTHORIZED,"Authorization failed");
|
||||
}
|
||||
sendResponse(response);
|
||||
}finally{
|
||||
if(this.service!=null)
|
||||
this.service.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ public abstract class AbstractFeedHandler extends RequestAuthenticator implement
|
|||
return this.errorMessage;
|
||||
}
|
||||
|
||||
class FeedHandlerException extends Exception{
|
||||
static class FeedHandlerException extends Exception{
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -41,7 +41,10 @@ public abstract class AbstractGdataRequestHandler extends RequestAuthenticator i
|
|||
GDataRequestHandler {
|
||||
private final static Log LOG = LogFactory
|
||||
.getLog(AbstractGdataRequestHandler.class);
|
||||
|
||||
/*
|
||||
* UTF-8 is the encoding used in the client API to send the entries to the server
|
||||
*/
|
||||
private final static String ENCODING = "UTF-8";
|
||||
protected Service service;
|
||||
protected GDataRequest feedRequest;
|
||||
protected GDataResponse feedResponse;
|
||||
|
@ -57,6 +60,7 @@ public abstract class AbstractGdataRequestHandler extends RequestAuthenticator i
|
|||
throws GDataRequestException, ServletException {
|
||||
this.feedRequest = new GDataRequest(request, type);
|
||||
this.feedResponse = new GDataResponse(response);
|
||||
this.feedResponse.setEncoding(ENCODING);
|
||||
getService();
|
||||
try {
|
||||
this.feedRequest.initializeRequest();
|
||||
|
|
|
@ -100,8 +100,14 @@ public class AuthenticationHandler implements GDataRequestHandler {
|
|||
|
||||
|
||||
private GDataAccount getAccount(String accountName) throws ServiceException{
|
||||
|
||||
AdminService service = this.serviceFactory.getAdminService();
|
||||
try{
|
||||
return service.getAccount(accountName);
|
||||
}finally{
|
||||
service.close();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
private void sendError(HttpServletResponse response, int code, String message)throws IOException{
|
||||
|
|
|
@ -75,9 +75,9 @@ public class DefaultDeleteHandler extends AbstractGdataRequestHandler {
|
|||
LOG.error("Could not process DeleteFeed request - "
|
||||
+ e.getMessage(), e);
|
||||
sendError();
|
||||
}
|
||||
}finally{
|
||||
closeService();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -102,9 +102,9 @@ public class DefaultGetHandler extends AbstractGdataRequestHandler {
|
|||
LOG.error("Could not process GetFeed request - " + e.getMessage(),
|
||||
e);
|
||||
sendError();
|
||||
}
|
||||
}finally{
|
||||
closeService();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -78,9 +78,9 @@ public class DefaultInsertHandler extends AbstractGdataRequestHandler {
|
|||
}catch (ServiceException e) {
|
||||
LOG.error("Could not process GetFeed request - "+e.getMessage(),e);
|
||||
this.feedResponse.sendError();
|
||||
}
|
||||
}finally{
|
||||
closeService();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -82,8 +82,9 @@ public class DefaultUpdateHandler extends AbstractGdataRequestHandler {
|
|||
LOG.error("Could not process UpdateFeed request - "
|
||||
+ e.getMessage(), e);
|
||||
sendError();
|
||||
}
|
||||
}finally{
|
||||
closeService();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.lucene.gdata.data.ServerBaseFeed;
|
||||
import org.apache.lucene.gdata.server.ServiceFactory;
|
||||
import org.apache.lucene.gdata.server.administration.AdminService;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
|
||||
|
||||
|
@ -44,6 +45,7 @@ public class DeleteFeedHandler extends AbstractFeedHandler{
|
|||
public void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
super.processRequest(request,response);
|
||||
if(this.authenticated){
|
||||
AdminService service = null;
|
||||
try {
|
||||
ServerBaseFeed feed = createDeleteFeed(request);
|
||||
|
||||
|
@ -53,13 +55,17 @@ public class DeleteFeedHandler extends AbstractFeedHandler{
|
|||
setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"required component is not available");
|
||||
throw new FeedHandlerException("Can't save feed - ServiceFactory is null");
|
||||
}
|
||||
serviceFactory.getAdminService().deleteFeed(feed);
|
||||
service = serviceFactory.getAdminService();
|
||||
service.deleteFeed(feed);
|
||||
} catch (FeedHandlerException e) {
|
||||
LOG.error("Can not delete feed -- "+e.getMessage(),e);
|
||||
}catch (Exception e) {
|
||||
LOG.error("Can not delete feed -- "+e.getMessage(),e);
|
||||
setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"can not create feed");
|
||||
}
|
||||
}finally{
|
||||
if(service != null)
|
||||
service.close();
|
||||
}
|
||||
}
|
||||
sendResponse(response);
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.apache.lucene.gdata.data.GDataAccount;
|
|||
import org.apache.lucene.gdata.data.ServerBaseFeed;
|
||||
import org.apache.lucene.gdata.server.ServiceException;
|
||||
import org.apache.lucene.gdata.server.ServiceFactory;
|
||||
import org.apache.lucene.gdata.server.administration.AdminService;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
|
||||
|
||||
|
@ -47,6 +48,7 @@ public class InsertFeedHandler extends AbstractFeedHandler {
|
|||
HttpServletResponse response) throws ServletException, IOException {
|
||||
super.processRequest(request, response);
|
||||
if (this.authenticated) {
|
||||
AdminService service = null;
|
||||
try {
|
||||
ServerBaseFeed feed = createFeedFromRequest(request);
|
||||
GDataAccount account = createRequestedAccount(request);
|
||||
|
@ -61,7 +63,8 @@ public class InsertFeedHandler extends AbstractFeedHandler {
|
|||
throw new FeedHandlerException(
|
||||
"Can't save feed - ServiceFactory is null");
|
||||
}
|
||||
serviceFactory.getAdminService().createFeed(feed, account);
|
||||
service = serviceFactory.getAdminService();
|
||||
service.createFeed(feed, account);
|
||||
} catch (ServiceException e) {
|
||||
setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
||||
"can not create feed");
|
||||
|
@ -69,6 +72,9 @@ public class InsertFeedHandler extends AbstractFeedHandler {
|
|||
} catch (Exception e) {
|
||||
LOG.error("Can not create feed -- " + e.getMessage(), e);
|
||||
|
||||
}finally{
|
||||
if(service != null)
|
||||
service.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -92,6 +92,11 @@ public class RequestAuthenticator implements GDataHttpAuthenticator {
|
|||
+ request.getFeedId(), e);
|
||||
throw new AuthenticatorException(" Service exception occured", e);
|
||||
|
||||
}finally{
|
||||
|
||||
if(adminService!=null)
|
||||
adminService.close();
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.apache.lucene.gdata.data.GDataAccount;
|
|||
import org.apache.lucene.gdata.data.ServerBaseFeed;
|
||||
import org.apache.lucene.gdata.server.ServiceException;
|
||||
import org.apache.lucene.gdata.server.ServiceFactory;
|
||||
import org.apache.lucene.gdata.server.administration.AdminService;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
|
||||
|
||||
|
@ -48,6 +49,7 @@ public class UpdateFeedHandler extends AbstractFeedHandler {
|
|||
HttpServletResponse response) throws ServletException, IOException {
|
||||
super.processRequest(request, response);
|
||||
if (this.authenticated) {
|
||||
AdminService service= null;
|
||||
try {
|
||||
ServerBaseFeed feed = createFeedFromRequest(request);
|
||||
GDataAccount account = createRequestedAccount(request);
|
||||
|
@ -62,7 +64,8 @@ public class UpdateFeedHandler extends AbstractFeedHandler {
|
|||
throw new FeedHandlerException(
|
||||
"Can't update feed - ServiceFactory is null");
|
||||
}
|
||||
serviceFactory.getAdminService().updateFeed(feed, account);
|
||||
service = serviceFactory.getAdminService();
|
||||
service.updateFeed(feed, account);
|
||||
} catch (ServiceException e) {
|
||||
setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
||||
"can not update feed");
|
||||
|
@ -71,10 +74,13 @@ public class UpdateFeedHandler extends AbstractFeedHandler {
|
|||
|
||||
LOG.error("Can not update feed -- " + e.getMessage(), e);
|
||||
|
||||
}finally{
|
||||
if(service != null)
|
||||
service.close();
|
||||
}
|
||||
}
|
||||
sendResponse(response);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.security.NoSuchAlgorithmException;
|
|||
import java.security.SecureRandom;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
@ -41,6 +42,8 @@ import org.apache.commons.logging.LogFactory;
|
|||
*
|
||||
*/
|
||||
public class IDGenerator {
|
||||
final AtomicBoolean stopped = new AtomicBoolean(false);
|
||||
|
||||
private final SecureRandom secureRandom;
|
||||
|
||||
private final MessageDigest mdigest;
|
||||
|
@ -110,8 +113,10 @@ public class IDGenerator {
|
|||
/**
|
||||
* Stops the id-producer
|
||||
*/
|
||||
public void stopIDGenerator() {
|
||||
public void stopIDGenerator() {
|
||||
this.stopped.set(true);
|
||||
this.runner.interrupt();
|
||||
|
||||
}
|
||||
|
||||
private class UIDProducer implements Runnable {
|
||||
|
@ -134,10 +139,10 @@ public class IDGenerator {
|
|||
*/
|
||||
public void run() {
|
||||
|
||||
while (true) {
|
||||
while (!IDGenerator.this.stopped.get()) {
|
||||
try {
|
||||
this.queue.put(produce());
|
||||
} catch (InterruptedException e) {
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER
|
||||
.warn("UIDProducer has been interrupted -- runner is going down");
|
||||
return;
|
||||
|
@ -147,7 +152,7 @@ public class IDGenerator {
|
|||
}
|
||||
|
||||
private String produce() {
|
||||
String randomNumber = new Integer(this.random.nextInt()).toString();
|
||||
String randomNumber = Integer.toString(this.random.nextInt());
|
||||
byte[] byteResult = this.digest.digest(randomNumber.getBytes());
|
||||
return hexEncode(byteResult);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* This exception will be thrown if a Version conflict occures while updateing
|
||||
* or deleteing an entry. Or if one entry is modified concurrently.
|
||||
*
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public class ModificationConflictException extends StorageException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructs a new ModificationConflictException
|
||||
*/
|
||||
public ModificationConflictException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ModificationConflictException
|
||||
*
|
||||
* @param message -
|
||||
* the exception message
|
||||
*/
|
||||
public ModificationConflictException(String message) {
|
||||
super(message);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ModificationConflictException
|
||||
*
|
||||
* @param message -
|
||||
* the exception message
|
||||
* @param cause -
|
||||
* the root cause of this exception
|
||||
*/
|
||||
public ModificationConflictException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ModificationConflictException
|
||||
*
|
||||
* @param cause -
|
||||
* the root cause of this exception
|
||||
*/
|
||||
public ModificationConflictException(Throwable cause) {
|
||||
super(cause);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -212,6 +212,8 @@ public interface Storage {
|
|||
throws StorageException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Retrieves the {@link GDataAccount} for the given account name
|
||||
* @param accountName -
|
||||
* the name of the requested account
|
||||
* @return - a {@link GDataAccount} instance for the requested account name
|
||||
|
|
|
@ -58,4 +58,10 @@ public interface StorageController extends ServerComponent {
|
|||
* if the storage instance can not be created
|
||||
*/
|
||||
public abstract Storage getStorage() throws StorageException;
|
||||
|
||||
/**
|
||||
* Releases a new unique ID
|
||||
* @return - unique ID
|
||||
*/
|
||||
public abstract String releaseId();
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ package org.apache.lucene.gdata.storage;
|
|||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public class StorageException extends Exception {
|
||||
public class StorageException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public interface ConcurrentStorageLock {
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean setLock(final String key);
|
||||
/**
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean releaseLock(final String key);
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean releaseThreadLocks();
|
||||
/**
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean isKeyLocked(final String key);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract void close();
|
||||
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/**
|
||||
* 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.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public class SingleHostConcurrentStorageLock implements ConcurrentStorageLock {
|
||||
private volatile static ConcurrentStorageLock INSTANCE = null;
|
||||
private final Map<String,Thread> locks;
|
||||
private final Map<Thread,String> threads;
|
||||
private final ReentrantReadWriteLock synLock = new ReentrantReadWriteLock();
|
||||
private final Lock readLock = this.synLock.readLock();
|
||||
private final Lock writeLock = this.synLock.writeLock();
|
||||
private final AtomicBoolean isClosed = new AtomicBoolean(false);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private SingleHostConcurrentStorageLock() {
|
||||
super();
|
||||
this.locks = new HashMap<String,Thread>(10);
|
||||
this.threads = new HashMap<Thread,String>(10);
|
||||
}
|
||||
protected static synchronized ConcurrentStorageLock getConcurrentStorageLock(){
|
||||
if(INSTANCE == null)
|
||||
INSTANCE = new SingleHostConcurrentStorageLock();
|
||||
return INSTANCE;
|
||||
}
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.ConcurrentStorageLock#setLock(java.lang.String)
|
||||
*/
|
||||
public boolean setLock(String key) {
|
||||
this.writeLock.lock();
|
||||
try{
|
||||
if(this.isClosed.get())
|
||||
throw new IllegalStateException("Lock has been closed");
|
||||
Thread t = Thread.currentThread();
|
||||
if(this.threads.containsKey(t))
|
||||
throw new ConcurrencyException("one thread must not obtain more than one lock -- single thread can not modify more than one resource");
|
||||
if(this.locks.containsKey(key)){
|
||||
return false;
|
||||
}
|
||||
this.locks.put(key, t);
|
||||
this.threads.put(t,key);
|
||||
return true;
|
||||
|
||||
}finally{
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.ConcurrentStorageLock#releaseLock(java.lang.String)
|
||||
*/
|
||||
public boolean releaseLock(String key) {
|
||||
this.writeLock.lock();
|
||||
try{
|
||||
if(this.isClosed.get())
|
||||
throw new IllegalStateException("Lock has been closed");
|
||||
Thread t = Thread.currentThread();
|
||||
if(!this.threads.containsKey(t))
|
||||
return false;
|
||||
|
||||
if(!this.locks.containsKey(key))
|
||||
return false;
|
||||
if(t != this.locks.get(key))
|
||||
throw new ConcurrencyException("Illegal lock access -- current thread is not owner");
|
||||
this.locks.remove(key);
|
||||
this.threads.remove(t);
|
||||
return true;
|
||||
|
||||
}finally{
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.ConcurrentStorageLock#releaseThreadLocks()
|
||||
*/
|
||||
public boolean releaseThreadLocks() {
|
||||
this.writeLock.lock();
|
||||
try{
|
||||
if(this.isClosed.get())
|
||||
throw new IllegalStateException("Lock has been closed");
|
||||
Thread t = Thread.currentThread();
|
||||
if(!this.threads.containsKey(t))
|
||||
return false;
|
||||
String key = this.threads.get(t);
|
||||
this.threads.remove(t);
|
||||
if(!this.locks.containsKey(key))
|
||||
return false;
|
||||
this.locks.remove(key);
|
||||
return true;
|
||||
|
||||
}finally{
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.ConcurrentStorageLock#isKeyLocked(java.lang.String)
|
||||
*/
|
||||
public boolean isKeyLocked(String key) {
|
||||
this.readLock.lock();
|
||||
try{
|
||||
if(this.isClosed.get())
|
||||
throw new IllegalStateException("Lock has been closed");
|
||||
return this.locks.containsKey(key);
|
||||
}finally{
|
||||
this.readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.ConcurrentStorageLock#close()
|
||||
*/
|
||||
public void close() {
|
||||
this.writeLock.lock();
|
||||
try{
|
||||
if(this.isClosed.get())
|
||||
throw new IllegalStateException("Lock has been closed");
|
||||
this.isClosed.set(true);
|
||||
this.locks.clear();
|
||||
this.threads.clear();
|
||||
INSTANCE = new SingleHostConcurrentStorageLock();
|
||||
}finally{
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void forceClear(){
|
||||
this.writeLock.lock();
|
||||
try{
|
||||
if(this.isClosed.get())
|
||||
throw new IllegalStateException("Lock has been closed");
|
||||
this.locks.clear();
|
||||
this.threads.clear();
|
||||
|
||||
}finally{
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
}
|
||||
static class ConcurrencyException extends RuntimeException{
|
||||
|
||||
private static final long serialVersionUID = 6388236477729760962L;
|
||||
|
||||
ConcurrencyException(String message){
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,6 +52,10 @@ import com.google.gdata.data.Link;
|
|||
* The read lock may be held simultaneously by multiple reader threads, so long
|
||||
* as there are no writers. The write lock is exclusive.
|
||||
* </p>
|
||||
* <p>
|
||||
* The entry and feed ID's must not be a composite key. The entry and feed ID
|
||||
* must be unique.
|
||||
* </p>
|
||||
*
|
||||
* @see java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier
|
||||
|
@ -61,255 +65,294 @@ import com.google.gdata.data.Link;
|
|||
*
|
||||
*/
|
||||
public class StorageBuffer {
|
||||
private static final Log LOG = LogFactory.getLog(StorageBuffer.class);
|
||||
private static final Log LOG = LogFactory.getLog(StorageBuffer.class);
|
||||
|
||||
private final Map<String, Map<String, StorageEntryWrapper>> bufferMap;
|
||||
private final Map<String, Map<String, StorageEntryWrapper>> bufferMap;
|
||||
|
||||
private final Map<String, Long> modifiyMap;
|
||||
private final Map<String, Long> modifiyMap;
|
||||
|
||||
private final List<String> excludeList;
|
||||
private final List<String> excludeList;
|
||||
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock(true);
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock(true);
|
||||
|
||||
private final Lock readLock = this.lock.readLock();
|
||||
private final Lock readLock = this.lock.readLock();
|
||||
|
||||
private final Lock writeLock = this.lock.writeLock();
|
||||
private final Lock writeLock = this.lock.writeLock();
|
||||
|
||||
private final static int DEFAULT_BUFFER_COUNT = 10;
|
||||
private final int bufferSize;
|
||||
|
||||
/**
|
||||
* Constructs a new StorageBuffer.
|
||||
* <p>
|
||||
* The expectedBufferCount sould be higher than the maximum of entries added
|
||||
* to the buffer, resizing the buffer is very efficient. For detailed
|
||||
* infomation {@link HashMap} as this is used inside the buffer
|
||||
* </p>
|
||||
*
|
||||
* @param expectedBufferCount -
|
||||
* the expected size of the buffer
|
||||
*
|
||||
*/
|
||||
protected StorageBuffer(final int expectedBufferCount) {
|
||||
this.bufferMap = new HashMap<String, Map<String, StorageEntryWrapper>>(
|
||||
expectedBufferCount < DEFAULT_BUFFER_COUNT ? DEFAULT_BUFFER_COUNT
|
||||
: expectedBufferCount);
|
||||
this.excludeList = new ArrayList<String>(
|
||||
expectedBufferCount < DEFAULT_BUFFER_COUNT ? DEFAULT_BUFFER_COUNT
|
||||
: expectedBufferCount);
|
||||
this.modifiyMap = new HashMap<String, Long>(
|
||||
expectedBufferCount < DEFAULT_BUFFER_COUNT ? DEFAULT_BUFFER_COUNT
|
||||
: expectedBufferCount);
|
||||
}
|
||||
protected final static int DEFAULT_BUFFER_COUNT = 10;
|
||||
|
||||
/**
|
||||
* Adds a {@link StorageEntryWrapper} to the buffer. If a wrapper
|
||||
* representing the same entry are already in the buffer the wrapper will be
|
||||
* replaced.
|
||||
*
|
||||
* @param wrapper -
|
||||
* the wrapper to buffer
|
||||
*/
|
||||
public void addEntry(final StorageEntryWrapper wrapper) {
|
||||
this.writeLock.lock();
|
||||
try {
|
||||
if (LOG.isInfoEnabled())
|
||||
LOG.info(" Buffering wrapper - " + wrapper.getOperation()
|
||||
+ " ID: " + wrapper.getEntryId() + " FeedID: "
|
||||
+ wrapper.getFeedId());
|
||||
if (wrapper.getOperation().equals(StorageOperation.DELETE))
|
||||
return;
|
||||
/**
|
||||
* Constructs a new StorageBuffer.
|
||||
* <p>
|
||||
* The expectedBufferCount sould be higher than the maximum of entries added
|
||||
* to the buffer, resizing the buffer is very efficient. For detailed
|
||||
* infomation {@link HashMap} as this is used inside the buffer
|
||||
* </p>
|
||||
*
|
||||
* @param expectedBufferCount -
|
||||
* the expected size of the buffer
|
||||
*
|
||||
*/
|
||||
protected StorageBuffer(final int expectedBufferCount) {
|
||||
this.bufferSize = expectedBufferCount < DEFAULT_BUFFER_COUNT ? DEFAULT_BUFFER_COUNT
|
||||
: expectedBufferCount;
|
||||
this.bufferMap = new HashMap<String, Map<String, StorageEntryWrapper>>(
|
||||
this.bufferSize);
|
||||
this.excludeList = new ArrayList<String>(this.bufferSize);
|
||||
this.modifiyMap = new HashMap<String, Long>(this.bufferSize);
|
||||
}
|
||||
|
||||
String feedId = wrapper.getFeedId();
|
||||
if (this.bufferMap.containsKey(feedId))
|
||||
this.bufferMap.get(feedId).put(wrapper.getEntryId(), wrapper);
|
||||
else {
|
||||
Map<String, StorageEntryWrapper> newFeedMap = new HashMap<String, StorageEntryWrapper>(
|
||||
20);
|
||||
newFeedMap.put(wrapper.getEntryId(), wrapper);
|
||||
this.bufferMap.put(feedId, newFeedMap);
|
||||
/**
|
||||
* Adds a {@link StorageEntryWrapper} to the buffer. If a wrapper
|
||||
* representing the same entry are already in the buffer the wrapper will be
|
||||
* replaced.
|
||||
* <p>
|
||||
* This method does ignore already delted entries. This should before the
|
||||
* entry is added to the buffer.
|
||||
* </p>
|
||||
*
|
||||
* @param wrapper -
|
||||
* the wrapper to buffer
|
||||
*/
|
||||
public void addEntry(final StorageEntryWrapper wrapper) {
|
||||
this.writeLock.lock();
|
||||
try {
|
||||
if (LOG.isInfoEnabled())
|
||||
LOG.info(" Buffering wrapper - " + wrapper.getOperation()
|
||||
+ " ID: " + wrapper.getEntryId() + " FeedID: "
|
||||
+ wrapper.getFeedId());
|
||||
if (wrapper.getOperation().equals(StorageOperation.DELETE))
|
||||
return;
|
||||
String feedId = wrapper.getFeedId();
|
||||
if (this.bufferMap.containsKey(feedId))
|
||||
this.bufferMap.get(feedId).put(wrapper.getEntryId(), wrapper);
|
||||
else {
|
||||
Map<String, StorageEntryWrapper> newFeedMap = new HashMap<String, StorageEntryWrapper>(
|
||||
20);
|
||||
newFeedMap.put(wrapper.getEntryId(), wrapper);
|
||||
this.bufferMap.put(feedId, newFeedMap);
|
||||
|
||||
}
|
||||
addLastModified(wrapper.getFeedId(), wrapper.getTimestamp());
|
||||
} finally {
|
||||
/*
|
||||
* add all to exclude from searches doc will be available via the
|
||||
* buffer
|
||||
*/
|
||||
this.excludeList.add(wrapper.getEntryId());
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
addLastModified(wrapper.getFeedId(), wrapper.getTimestamp());
|
||||
/*
|
||||
* add to exclude from searches doc will be available via the buffer
|
||||
* if the entry is not already in the buffer
|
||||
*/
|
||||
if (!this.excludeList.contains(wrapper.getEntryId()))
|
||||
this.excludeList.add(wrapper.getEntryId());
|
||||
} finally {
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void addLastModified(final String feedId, Long timestamp) {
|
||||
if (this.modifiyMap.containsKey(feedId))
|
||||
this.modifiyMap.remove(feedId);
|
||||
this.modifiyMap.put(feedId, timestamp);
|
||||
private void addLastModified(final String feedId, Long timestamp) {
|
||||
this.writeLock.lock();
|
||||
try {
|
||||
if (this.modifiyMap.containsKey(feedId))
|
||||
this.modifiyMap.remove(feedId);
|
||||
this.modifiyMap.put(feedId, timestamp);
|
||||
} finally {
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected Long getFeedLastModified(final String feedId) {
|
||||
return this.modifiyMap.get(feedId);
|
||||
}
|
||||
/**
|
||||
* the timestamp of the last modification for the given feed id
|
||||
*
|
||||
* @param feedId -
|
||||
* feed id
|
||||
* @return timestamp
|
||||
*/
|
||||
protected Long getFeedLastModified(final String feedId) {
|
||||
this.readLock.lock();
|
||||
try {
|
||||
return this.modifiyMap.get(feedId);
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
protected Set<Entry<String, Long>> getLastModified() {
|
||||
return this.modifiyMap.entrySet();
|
||||
}
|
||||
protected Set<Entry<String, Long>> getLastModified() {
|
||||
return this.modifiyMap.entrySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all entries for the given feed id sorted by the update timestamp
|
||||
* desc.
|
||||
*
|
||||
* @param feedId -
|
||||
* the feed id
|
||||
* @return a {@link List} of all {@link StorageEntryWrapper} object buffered
|
||||
* in this buffer or an empty list if not entry has been buffered
|
||||
* for the given feed
|
||||
*/
|
||||
public List<StorageEntryWrapper> getSortedEntries(String feedId) {
|
||||
this.readLock.lock();
|
||||
try {
|
||||
if (!this.bufferMap.containsKey(feedId))
|
||||
return null;
|
||||
Map<String, StorageEntryWrapper> tempMap = this.bufferMap
|
||||
.get(feedId);
|
||||
if (tempMap == null)
|
||||
return null;
|
||||
Collection<StorageEntryWrapper> col = tempMap.values();
|
||||
List<StorageEntryWrapper> returnList = new ArrayList<StorageEntryWrapper>(
|
||||
col);
|
||||
Collections.sort(returnList);
|
||||
return returnList;
|
||||
/**
|
||||
* Returns all entries for the given feed id sorted by the update timestamp
|
||||
* desc.
|
||||
*
|
||||
* @param feedId -
|
||||
* the feed id
|
||||
* @return a {@link List} of all {@link StorageEntryWrapper} object buffered
|
||||
* in this buffer or an empty list if not entry has been buffered
|
||||
* for the given feed
|
||||
*/
|
||||
public List<StorageEntryWrapper> getSortedEntries(String feedId) {
|
||||
this.readLock.lock();
|
||||
try {
|
||||
if (!this.bufferMap.containsKey(feedId))
|
||||
return null;
|
||||
Map<String, StorageEntryWrapper> tempMap = this.bufferMap
|
||||
.get(feedId);
|
||||
if (tempMap == null)
|
||||
return null;
|
||||
Collection<StorageEntryWrapper> col = tempMap.values();
|
||||
List<StorageEntryWrapper> returnList = new ArrayList<StorageEntryWrapper>(
|
||||
col);
|
||||
Collections.sort(returnList);
|
||||
return returnList;
|
||||
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
}
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a deleted entry to the buffer.
|
||||
*
|
||||
* @param entryId -
|
||||
* the deleted entry id
|
||||
* @param feedId -
|
||||
* the feed of the entry
|
||||
*/
|
||||
public void addDeleted(final String entryId, final String feedId) {
|
||||
this.writeLock.lock();
|
||||
try {
|
||||
this.excludeList.add(entryId);
|
||||
Map<String, StorageEntryWrapper> tempMap = this.bufferMap
|
||||
.get(feedId);
|
||||
if (tempMap == null)
|
||||
return;
|
||||
tempMap.remove(entryId);
|
||||
this.addLastModified(feedId, new Long(System.currentTimeMillis()));
|
||||
} finally {
|
||||
this.writeLock.unlock();
|
||||
/**
|
||||
* Adds a deleted entry to the buffer.
|
||||
*
|
||||
* @param entryId -
|
||||
* the deleted entry id
|
||||
* @param feedId -
|
||||
* the feed of the entry
|
||||
*/
|
||||
public void addDeleted(final String entryId, final String feedId) {
|
||||
this.writeLock.lock();
|
||||
try {
|
||||
Map<String, StorageEntryWrapper> tempMap = this.bufferMap
|
||||
.get(feedId);
|
||||
if (tempMap != null) {
|
||||
tempMap.remove(entryId);
|
||||
this.addLastModified(feedId, new Long(System
|
||||
.currentTimeMillis()));
|
||||
}
|
||||
/*
|
||||
* add to exclude from searches
|
||||
*/
|
||||
if (!this.excludeList.contains(entryId))
|
||||
this.excludeList.add(entryId);
|
||||
} finally {
|
||||
|
||||
}
|
||||
this.writeLock.unlock();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an entry for the given entry id in the feed context spezified by
|
||||
* the feed id;
|
||||
*
|
||||
* @param entryId -
|
||||
* the id of the entry to return
|
||||
* @param feedId -
|
||||
* the feed containing the entry
|
||||
* @return - the entry or <code>null</code> if the corresponding entry is
|
||||
* not in the buffer.
|
||||
*/
|
||||
public StorageEntryWrapper getEntry(final String entryId,
|
||||
final String feedId) {
|
||||
this.readLock.lock();
|
||||
try {
|
||||
}
|
||||
|
||||
if (this.bufferMap.containsKey(feedId))
|
||||
return this.bufferMap.get(feedId).get(entryId);
|
||||
return null;
|
||||
/**
|
||||
* Returns an entry for the given entry id in the feed context spezified by
|
||||
* the feed id;
|
||||
*
|
||||
* @param entryId -
|
||||
* the id of the entry to return
|
||||
* @param feedId -
|
||||
* the feed containing the entry
|
||||
* @return - the entry or <code>null</code> if the corresponding entry is
|
||||
* not in the buffer.
|
||||
*/
|
||||
public StorageEntryWrapper getEntry(final String entryId,
|
||||
final String feedId) {
|
||||
this.readLock.lock();
|
||||
try {
|
||||
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
}
|
||||
}
|
||||
if (this.bufferMap.containsKey(feedId))
|
||||
return this.bufferMap.get(feedId).get(entryId);
|
||||
return null;
|
||||
|
||||
/**
|
||||
* The buffer contains updated and delete entries. These entries are already
|
||||
* available in the lucene index but should not be found during search.
|
||||
*
|
||||
* <p>
|
||||
* This list contains all entries should not be found by the index searcher.
|
||||
* This method creates a copy of the current list to prevent concurrent
|
||||
* modification exceptions while iteration over the collection.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @see ModifiedEntryFilter
|
||||
* @return - a String array of entries to be omitted from a lucene index
|
||||
* search
|
||||
*/
|
||||
public String[] getExculdList() {
|
||||
this.readLock.lock();
|
||||
try {
|
||||
return this.excludeList
|
||||
.toArray(new String[this.excludeList.size()]);
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// not synchronized
|
||||
private void clearBuffer() {
|
||||
this.bufferMap.clear();
|
||||
this.excludeList.clear();
|
||||
this.modifiyMap.clear();
|
||||
/**
|
||||
* The buffer contains updated and delete entries. These entries are already
|
||||
* available in the lucene index but should not be found during search.
|
||||
*
|
||||
* <p>
|
||||
* This list contains all entries should not be found by the index searcher.
|
||||
* This method creates a copy of the current list to prevent concurrent
|
||||
* modification exceptions while iteration over the collection.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @see ModifiedEntryFilter
|
||||
* @return - a String array of entries to be omitted from a lucene index
|
||||
* search
|
||||
*/
|
||||
public String[] getExculdList() {
|
||||
this.readLock.lock();
|
||||
try {
|
||||
return this.excludeList
|
||||
.toArray(new String[this.excludeList.size()]);
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// not synchronized --> see close()
|
||||
private void clearBuffer() {
|
||||
|
||||
/**
|
||||
* clears the buffer -
|
||||
*/
|
||||
public void close() {
|
||||
this.writeLock.lock();
|
||||
try {
|
||||
clearBuffer();
|
||||
} finally {
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
this.bufferMap.clear();
|
||||
this.excludeList.clear();
|
||||
this.modifiyMap.clear();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class BufferableEntry extends BaseEntry {
|
||||
/**
|
||||
* clears the buffer -
|
||||
*/
|
||||
public void close() {
|
||||
this.writeLock.lock();
|
||||
try {
|
||||
clearBuffer();
|
||||
} finally {
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public BufferableEntry() {
|
||||
super();
|
||||
this.links = new LinkedList<Link>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param arg0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public BufferableEntry(BaseEntry arg0) {
|
||||
super(arg0);
|
||||
this.links = new LinkedList<Link>();
|
||||
}
|
||||
static class BufferableEntry extends BaseEntry {
|
||||
|
||||
/**
|
||||
* @see com.google.gdata.data.BaseEntry#declareExtensions(com.google.gdata.data.ExtensionProfile)
|
||||
*/
|
||||
@Override
|
||||
public void declareExtensions(ExtensionProfile arg0) {
|
||||
//
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public BufferableEntry() {
|
||||
super();
|
||||
this.links = new LinkedList<Link>();
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @param arg0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public BufferableEntry(BaseEntry arg0) {
|
||||
super(arg0);
|
||||
if (this.links.size() > 0) {
|
||||
LinkedList list = new LinkedList<Link>();
|
||||
list.addAll(this.links);
|
||||
this.links = list;
|
||||
} else
|
||||
this.links = new LinkedList<Link>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.google.gdata.data.BaseEntry#declareExtensions(com.google.gdata.data.ExtensionProfile)
|
||||
*/
|
||||
@Override
|
||||
public void declareExtensions(ExtensionProfile arg0) {
|
||||
//
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the bufferSize.
|
||||
*/
|
||||
public int getBufferSize() {
|
||||
return this.bufferSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,18 +12,18 @@ import org.apache.lucene.analysis.standard.StandardAnalyzer;
|
|||
import org.apache.lucene.gdata.data.GDataAccount;
|
||||
import org.apache.lucene.gdata.server.registry.Component;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.server.registry.configuration.Requiered;
|
||||
import org.apache.lucene.gdata.storage.IDGenerator;
|
||||
import org.apache.lucene.gdata.storage.Storage;
|
||||
import org.apache.lucene.gdata.storage.StorageController;
|
||||
import org.apache.lucene.gdata.storage.StorageException;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.configuration.StorageConfigurator;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.recover.RecoverController;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.recover.RecoverException;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter;
|
||||
import org.apache.lucene.index.IndexModifier;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.FSDirectory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -33,14 +33,15 @@ import org.apache.lucene.store.RAMDirectory;
|
|||
*/
|
||||
@Component(componentType = ComponentType.STORAGECONTROLLER)
|
||||
public class StorageCoreController implements StorageController {
|
||||
|
||||
protected static final Log LOG = LogFactory
|
||||
.getLog(StorageCoreController.class);
|
||||
|
||||
private IndexSearcher searcher;
|
||||
|
||||
private final Directory storageDir;
|
||||
private Directory storageDir;
|
||||
|
||||
private final StorageModifier modifier;
|
||||
private StorageModifier modifier;
|
||||
|
||||
private ReferenceCounter<StorageQuery> storageQuery;
|
||||
|
||||
|
@ -49,39 +50,39 @@ public class StorageCoreController implements StorageController {
|
|||
private final ReentrantLock storageControllerLock = new ReentrantLock();
|
||||
private final Condition closeCondition;
|
||||
|
||||
private static final int DEFAULT_STORAGE_BUFFER_SIZE = 10;
|
||||
private static final int DEFAULT_STORAGE_BUFFER_SIZE = 3;
|
||||
|
||||
private static final int DEFAULT_STORAGE_PERSIST_FACTOR = 10;
|
||||
private static final int DEFAULT_STORAGE_PERSIST_FACTOR = 3;
|
||||
|
||||
private static final String RECOVERDIRECTORY = "recover";
|
||||
|
||||
private static final String STORAGELOG = ".lucenestorage";
|
||||
|
||||
private IDGenerator idGenerator;
|
||||
|
||||
private final ConcurrentStorageLock storageLock;
|
||||
/*
|
||||
*properties set by configuration file e.g. Registry
|
||||
*/
|
||||
private int indexOptimizeInterval;
|
||||
|
||||
private String storageDirectory;
|
||||
|
||||
private boolean keepRecoveredFiles;
|
||||
|
||||
private boolean recover;
|
||||
|
||||
private int storageBufferSize;
|
||||
|
||||
private int storagePersistFactor;
|
||||
|
||||
private StorageConfigurator configurator;
|
||||
|
||||
private IDGenerator idGenerator;
|
||||
|
||||
private int indexOptimizeInterval;
|
||||
|
||||
// private RecoverController recoverController;
|
||||
|
||||
private RecoverController recoverController;
|
||||
/**
|
||||
* Creates a new <tt>StoragCoreController</tt> and sets up the storage
|
||||
* environment reading the configuration file.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @throws IOException -
|
||||
* if an IOException occures
|
||||
* @throws StorageException -
|
||||
* if the storage lock can not be created or the
|
||||
* {@link IDGenerator} can not be loaded
|
||||
* @see org.apache.lucene.gdata.server.registry.ServerComponent#initialize()
|
||||
*/
|
||||
public StorageCoreController() throws IOException, StorageException {
|
||||
public void initialize() {
|
||||
synchronized (StorageCoreController.class) {
|
||||
this.closeCondition = this.storageControllerLock.newCondition();
|
||||
|
||||
try {
|
||||
this.idGenerator = new IDGenerator(10);
|
||||
} catch (Exception e) {
|
||||
|
@ -89,11 +90,11 @@ public class StorageCoreController implements StorageController {
|
|||
}
|
||||
|
||||
boolean createNewStorage = false;
|
||||
this.configurator = StorageConfigurator.getStorageConfigurator();
|
||||
if (!this.configurator.isRamDirectory()) {
|
||||
|
||||
if (this.storageDir == null) {
|
||||
|
||||
String storageDirPath = this.configurator.getStorageDirectory();
|
||||
File storeDir = new File(storageDirPath);
|
||||
|
||||
File storeDir = new File(this.storageDirectory);
|
||||
File storageLog = new File(storeDir.getAbsolutePath()
|
||||
+ System.getProperty("file.separator") + STORAGELOG);
|
||||
try {
|
||||
|
@ -106,35 +107,83 @@ public class StorageCoreController implements StorageController {
|
|||
} else
|
||||
throw new StorageException(
|
||||
"could not create storage lock file in "
|
||||
+ storageDirPath);
|
||||
+ this.storageDirectory);
|
||||
|
||||
} else
|
||||
this.storageDir = FSDirectory.getDirectory(storeDir,
|
||||
false);
|
||||
} catch (IOException e) {
|
||||
storageLog.delete();
|
||||
throw e;
|
||||
throw new StorageException(e);
|
||||
}
|
||||
this.indexOptimizeInterval = this.configurator
|
||||
.getIndexOptimizeInterval();
|
||||
this.storageBufferSize = this.configurator
|
||||
.getStorageBufferSize() < DEFAULT_STORAGE_BUFFER_SIZE ? DEFAULT_STORAGE_BUFFER_SIZE
|
||||
: this.configurator.getStorageBufferSize();
|
||||
this.storagePersistFactor = this.configurator
|
||||
.getStoragepersistFactor() < DEFAULT_STORAGE_PERSIST_FACTOR ? DEFAULT_STORAGE_PERSIST_FACTOR
|
||||
: this.configurator.getStoragepersistFactor();
|
||||
|
||||
this.storageBufferSize = this.storageBufferSize < DEFAULT_STORAGE_BUFFER_SIZE ? DEFAULT_STORAGE_BUFFER_SIZE
|
||||
: this.storageBufferSize;
|
||||
this.storagePersistFactor = this.storagePersistFactor < DEFAULT_STORAGE_PERSIST_FACTOR ? DEFAULT_STORAGE_PERSIST_FACTOR
|
||||
: this.storagePersistFactor;
|
||||
|
||||
} else
|
||||
this.storageDir = getRamDirectory();
|
||||
}else
|
||||
createNewStorage = true;
|
||||
|
||||
|
||||
this.currentBuffer = new StorageBuffer(this.storageBufferSize);
|
||||
try{
|
||||
this.modifier = createStorageModifier(createNewStorage);
|
||||
this.searcher = new IndexSearcher(this.storageDir);
|
||||
// this.recoverController = new RecoverController(null,this.configurator.isRecover(),this.configurator.isKeepRecoveredFiles());
|
||||
}catch (Exception e) {
|
||||
throw new StorageException("Can not create Searcher/Modifier -- "+e.getMessage(),e);
|
||||
}
|
||||
|
||||
|
||||
if(createNewStorage)
|
||||
createAdminAccount();
|
||||
if(!this.recover)
|
||||
return;
|
||||
try{
|
||||
tryRecover();
|
||||
}catch (Exception e) {
|
||||
LOG.fatal("Recovering failed",e);
|
||||
throw new StorageException("Recovering failed -- "+e.getMessage(),e);
|
||||
}
|
||||
|
||||
this.recoverController = createRecoverController(false,false);
|
||||
try{
|
||||
this.recoverController.initialize();
|
||||
}catch (Exception e) {
|
||||
LOG.fatal("Can not initialize recover controller",e);
|
||||
throw new StorageException("Can not initialize recover controller -- "+e.getMessage(),e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* reads the remaining recover files to store the failed entries
|
||||
*/
|
||||
private void tryRecover() throws IOException, RecoverException{
|
||||
if(!this.recover)
|
||||
return;
|
||||
LOG.info("try to recover files if there are any");
|
||||
this.recoverController = createRecoverController(true,false);
|
||||
this.recoverController.initialize();
|
||||
this.recoverController.recoverEntries(this.modifier);
|
||||
this.recoverController.destroy();
|
||||
}
|
||||
|
||||
private RecoverController createRecoverController(boolean doRecover, boolean keepfiles){
|
||||
String recoverDirectory = null;
|
||||
if(this.storageDirectory.endsWith("/") || this.storageDirectory.endsWith("\\"))
|
||||
recoverDirectory = this.storageDirectory.substring(0,this.storageDirectory.length()-1)+System.getProperty("file.separator")+RECOVERDIRECTORY;
|
||||
else
|
||||
recoverDirectory = this.storageDirectory+System.getProperty("file.separator")+RECOVERDIRECTORY;
|
||||
File recoverDirectoryFile = new File(recoverDirectory);
|
||||
return new RecoverController(recoverDirectoryFile,doRecover,keepfiles);
|
||||
}
|
||||
/**
|
||||
* Creates a new <tt>StoragCoreController</tt>
|
||||
*/
|
||||
public StorageCoreController() {
|
||||
this.closeCondition = this.storageControllerLock.newCondition();
|
||||
this.storageLock = SingleHostConcurrentStorageLock.getConcurrentStorageLock();
|
||||
|
||||
}
|
||||
|
||||
|
@ -188,7 +237,9 @@ public class StorageCoreController implements StorageController {
|
|||
this.storageQuery.increamentReference();
|
||||
return this.storageQuery;
|
||||
}finally{
|
||||
try{
|
||||
this.closeCondition.signalAll();
|
||||
}catch (Throwable e) {/**/}
|
||||
this.storageControllerLock.unlock();
|
||||
}
|
||||
}
|
||||
|
@ -239,7 +290,9 @@ public class StorageCoreController implements StorageController {
|
|||
this.currentBuffer = new StorageBuffer(this.storageBufferSize);
|
||||
|
||||
}finally{
|
||||
this.closeCondition.signalAll();
|
||||
try{
|
||||
this.closeCondition.signalAll();
|
||||
}catch (Throwable e) {/**/}
|
||||
this.storageControllerLock.unlock();
|
||||
}
|
||||
|
||||
|
@ -259,7 +312,9 @@ public class StorageCoreController implements StorageController {
|
|||
throw new IllegalStateException("StorageController is already closed -- server is shutting down");
|
||||
return this.currentBuffer;
|
||||
}finally{
|
||||
try{
|
||||
this.closeCondition.signalAll();
|
||||
}catch (Throwable e) {/**/}
|
||||
this.storageControllerLock.unlock();
|
||||
}
|
||||
}
|
||||
|
@ -284,7 +339,9 @@ public class StorageCoreController implements StorageController {
|
|||
return new IndexModifier(this.storageDir, new StandardAnalyzer(),
|
||||
false);
|
||||
}finally{
|
||||
this.closeCondition.signalAll();
|
||||
try{
|
||||
this.closeCondition.signalAll();
|
||||
}catch (Throwable e) {/**/}
|
||||
this.storageControllerLock.unlock();
|
||||
}
|
||||
}
|
||||
|
@ -308,48 +365,16 @@ public class StorageCoreController implements StorageController {
|
|||
LOG.info("StorageController has been closed -- server is shutting down -- release all resources");
|
||||
if (this.storageQuery != null)
|
||||
this.storageQuery.decrementRef();
|
||||
if(this.recoverController != null)
|
||||
this.recoverController.destroy();
|
||||
this.storageLock.close();
|
||||
this.modifier.close();
|
||||
this.idGenerator.stopIDGenerator();
|
||||
}finally{
|
||||
this.storageControllerLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the <tt>StorageBuffer</tt>.
|
||||
*
|
||||
* @return - storage buffer size
|
||||
*/
|
||||
public int getStorageBufferSize() {
|
||||
return this.storageBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the <tt>StorageBuffer</tt>. This size should be at least
|
||||
* as big as the persist factor to prevent the <tt>StorageBuffer</tt> from
|
||||
* resizing
|
||||
*
|
||||
* @param storageBufferSize
|
||||
*/
|
||||
public void setStorageBufferSize(int storageBufferSize) {
|
||||
this.storageBufferSize = storageBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* An integer value after how many changes to the StorageModifier the
|
||||
* buffered changes will be persisted / wirtten to the index
|
||||
*
|
||||
* @return - the persist factor
|
||||
*/
|
||||
public int getStoragePersistFactor() {
|
||||
return this.storagePersistFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param storagePersistFactor
|
||||
*/
|
||||
public void setStoragePersistFactor(int storagePersistFactor) {
|
||||
this.storagePersistFactor = storagePersistFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the StorageModifier to write all buffered changes.
|
||||
|
@ -364,12 +389,13 @@ public class StorageCoreController implements StorageController {
|
|||
this.modifier.forceWrite();
|
||||
}
|
||||
|
||||
private boolean createLuceneStorageLog(File storageDirectory)
|
||||
private boolean createLuceneStorageLog(File directory)
|
||||
throws IOException {
|
||||
if (storageDirectory.isDirectory() && !storageDirectory.exists()) {
|
||||
storageDirectory.createNewFile();
|
||||
if (directory.isDirectory() && !directory.exists()) {
|
||||
if(!directory.createNewFile())
|
||||
throw new StorageException("Can not create directory -- "+directory);
|
||||
}
|
||||
File file = new File(storageDirectory.getAbsolutePath()
|
||||
File file = new File(directory.getAbsolutePath()
|
||||
+ System.getProperty("file.separator") + STORAGELOG);
|
||||
return file.createNewFile();
|
||||
|
||||
|
@ -383,7 +409,7 @@ public class StorageCoreController implements StorageController {
|
|||
* @throws StorageException -
|
||||
* if no id can be released
|
||||
*/
|
||||
public synchronized String releaseID() throws StorageException {
|
||||
public synchronized String releaseId() {
|
||||
try {
|
||||
return this.idGenerator.getUID();
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -427,26 +453,142 @@ public class StorageCoreController implements StorageController {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO Try to remove this --> testcases
|
||||
private RAMDirectory getRamDirectory() throws IOException {
|
||||
IndexWriter writer;
|
||||
RAMDirectory retVal = new RAMDirectory();
|
||||
writer = new IndexWriter(retVal, new StandardAnalyzer(), true);
|
||||
writer.close();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.server.registry.ServerComponent#initialize()
|
||||
*/
|
||||
public void initialize() {
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void createAdminAccount() throws StorageException{
|
||||
GDataAccount adminAccount = GDataAccount.createAdminAccount();
|
||||
StorageAccountWrapper wrapper = new StorageAccountWrapper(adminAccount);
|
||||
this.getStorageModifier().createAccount(wrapper);
|
||||
}
|
||||
|
||||
protected ConcurrentStorageLock getLock(){
|
||||
return this.storageLock;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The size of the <tt>StorageBuffer</tt>.
|
||||
*
|
||||
* @return - storage buffer size
|
||||
*/
|
||||
public int getBufferSize() {
|
||||
return this.storageBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the <tt>StorageBuffer</tt>. This size should be at least
|
||||
* as big as the persist factor to prevent the <tt>StorageBuffer</tt> from
|
||||
* resizing
|
||||
*
|
||||
* @param storageBufferSize
|
||||
*/
|
||||
@Requiered
|
||||
public void setBufferSize(int storageBufferSize) {
|
||||
this.storageBufferSize = storageBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* An integer value after how many changes to the StorageModifier the
|
||||
* buffered changes will be persisted / wirtten to the index
|
||||
*
|
||||
* @return - the persist factor
|
||||
*/
|
||||
public int getPersistFactor() {
|
||||
return this.storagePersistFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param storagePersistFactor
|
||||
*/
|
||||
@Requiered
|
||||
public void setPersistFactor(int storagePersistFactor) {
|
||||
this.storagePersistFactor = storagePersistFactor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Returns the indexOptimizeInterval.
|
||||
*/
|
||||
public int getIndexOptimizeInterval() {
|
||||
return this.indexOptimizeInterval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param indexOptimizeInterval The indexOptimizeInterval to set.
|
||||
*/
|
||||
@Requiered
|
||||
public void setOptimizeInterval(int indexOptimizeInterval) {
|
||||
this.indexOptimizeInterval = indexOptimizeInterval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Returns the keepRecoveredFiles.
|
||||
*/
|
||||
public boolean isKeepRecoveredFiles() {
|
||||
return this.keepRecoveredFiles;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param keepRecoveredFiles The keepRecoveredFiles to set.
|
||||
*/
|
||||
@Requiered
|
||||
public void setKeepRecoveredFiles(boolean keepRecoveredFiles) {
|
||||
this.keepRecoveredFiles = keepRecoveredFiles;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return Returns the recover.
|
||||
*/
|
||||
public boolean isRecover() {
|
||||
return this.recover;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param recover The recover to set.
|
||||
*/
|
||||
@Requiered
|
||||
public void setRecover(boolean recover) {
|
||||
this.recover = recover;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param storageDir The storageDir to set.
|
||||
*/
|
||||
|
||||
public void setStorageDir(Directory storageDir) {
|
||||
this.storageDir = storageDir;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param storageDirectory The storageDirectory to set.
|
||||
*/
|
||||
@Requiered
|
||||
public void setDirectory(String storageDirectory) {
|
||||
this.storageDirectory = storageDirectory;
|
||||
}
|
||||
|
||||
protected void writeRecoverEntry(StorageEntryWrapper wrapper) throws RecoverException{
|
||||
if(this.recoverController!= null &&!this.recoverController.isRecovering() )
|
||||
this.recoverController.storageModified(wrapper);
|
||||
}
|
||||
protected void registerNewRecoverWriter() throws IOException {
|
||||
if(this.recoverController == null || this.recoverController.isRecovering())
|
||||
return;
|
||||
this.recoverController.destroy();
|
||||
this.recoverController = createRecoverController(false,false);
|
||||
this.recoverController.initialize();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.lucene.gdata.storage.lucenestorage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
|
@ -37,11 +38,13 @@ import com.google.gdata.util.common.xml.XmlWriter;
|
|||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public class StorageEntryWrapper implements Comparable<StorageEntryWrapper>,
|
||||
public class StorageEntryWrapper implements Comparable<StorageEntryWrapper>, Serializable,
|
||||
StorageWrapper {
|
||||
|
||||
private static final long serialVersionUID = -4619985652059888526L;
|
||||
|
||||
/*
|
||||
* client api uses UTF-8 to encode server requests and entries
|
||||
*/
|
||||
private static final String INTERNAL_ENCODING = "UTF-8";
|
||||
|
||||
/**
|
||||
|
@ -64,21 +67,27 @@ public class StorageEntryWrapper implements Comparable<StorageEntryWrapper>,
|
|||
*/
|
||||
public final static String FIELD_TIMESTAMP = "timestamp";
|
||||
|
||||
private final String entryId;
|
||||
/**
|
||||
* lucene field name entry version
|
||||
*/
|
||||
public final static String FIELD_VERSION = "entryVersion";
|
||||
private int version;
|
||||
|
||||
private final String feedId;
|
||||
private String entryId;
|
||||
|
||||
private String feedId;
|
||||
|
||||
private String content;
|
||||
|
||||
private final ServerBaseEntry entry;
|
||||
private transient ServerBaseEntry entry;
|
||||
|
||||
private Long timestamp;
|
||||
|
||||
private transient Document document;
|
||||
private Document document;
|
||||
|
||||
private StorageOperation operation;
|
||||
|
||||
private ProvidedService config;
|
||||
private transient ProvidedService config;
|
||||
|
||||
/**
|
||||
* Creates a new StorageEntryWrapper.
|
||||
|
@ -94,14 +103,15 @@ public class StorageEntryWrapper implements Comparable<StorageEntryWrapper>,
|
|||
*/
|
||||
public StorageEntryWrapper(final ServerBaseEntry entry,
|
||||
StorageOperation operation) throws IOException {
|
||||
|
||||
this.entry = entry;
|
||||
this.operation = operation;
|
||||
this.entryId = entry.getId();
|
||||
this.feedId = entry.getFeedId();
|
||||
this.version = entry.getVersion();
|
||||
if (operation != StorageOperation.DELETE) {
|
||||
this.config = entry.getServiceConfig();
|
||||
this.content = buildContent();
|
||||
|
||||
|
||||
}
|
||||
this.timestamp = new Long(
|
||||
|
@ -110,7 +120,8 @@ public class StorageEntryWrapper implements Comparable<StorageEntryWrapper>,
|
|||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private String buildContent() throws IOException {
|
||||
StringWriter writer = new StringWriter();
|
||||
XmlWriter xmlWriter = new XmlWriter(writer, INTERNAL_ENCODING);
|
||||
|
@ -132,10 +143,12 @@ public class StorageEntryWrapper implements Comparable<StorageEntryWrapper>,
|
|||
Field.Store.YES, Field.Index.UN_TOKENIZED));
|
||||
this.document.add(new Field(FIELD_FEED_REFERENCE, this.feedId,
|
||||
Field.Store.YES, Field.Index.UN_TOKENIZED));
|
||||
this.document.add(new Field(FIELD_CONTENT, this.content,
|
||||
this.document.add(new Field(FIELD_CONTENT,this.content,
|
||||
Field.Store.COMPRESS, Field.Index.NO));
|
||||
this.document.add(new Field(FIELD_TIMESTAMP, this.timestamp.toString(),
|
||||
Field.Store.YES, Field.Index.UN_TOKENIZED));
|
||||
this.document.add(new Field(FIELD_VERSION, Integer.toString(this.version),
|
||||
Field.Store.YES, Field.Index.UN_TOKENIZED));
|
||||
|
||||
return this.document;
|
||||
|
||||
|
@ -205,7 +218,7 @@ public class StorageEntryWrapper implements Comparable<StorageEntryWrapper>,
|
|||
*
|
||||
*/
|
||||
public int compareTo(StorageEntryWrapper arg0) {
|
||||
return arg0.timestamp == this.timestamp ? 0
|
||||
return arg0.timestamp.equals(this.timestamp) ? 0
|
||||
: (arg0.timestamp > this.timestamp ? 1 : -1);
|
||||
}
|
||||
|
||||
|
@ -223,4 +236,14 @@ public class StorageEntryWrapper implements Comparable<StorageEntryWrapper>,
|
|||
return this.timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return - the version of the entry
|
||||
*/
|
||||
public int getVersion() {
|
||||
|
||||
return this.version;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.lucene.gdata.data.ServerBaseEntry;
|
|||
import org.apache.lucene.gdata.data.ServerBaseFeed;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
|
||||
import org.apache.lucene.gdata.storage.ModificationConflictException;
|
||||
import org.apache.lucene.gdata.storage.ResourceNotFoundException;
|
||||
import org.apache.lucene.gdata.storage.Storage;
|
||||
import org.apache.lucene.gdata.storage.StorageController;
|
||||
|
@ -76,11 +77,16 @@ public class StorageImplementation implements Storage {
|
|||
*/
|
||||
public BaseEntry storeEntry(final ServerBaseEntry entry)
|
||||
throws StorageException {
|
||||
|
||||
if (entry == null)
|
||||
throw new StorageException("entry is null");
|
||||
if(entry.getFeedId() == null)
|
||||
throw new StorageException("feedid is null");
|
||||
if(entry.getVersion() != 1)
|
||||
throw new StorageException("entry version must be 1");
|
||||
if(entry.getServiceConfig() == null)
|
||||
throw new StorageException("ProvidedService must not be null");
|
||||
StorageModifier modifier = this.controller.getStorageModifier();
|
||||
String id = this.controller.releaseID();
|
||||
String id = this.controller.releaseId();
|
||||
entry.setId(entry.getFeedId() + id);
|
||||
if (LOG.isInfoEnabled())
|
||||
LOG.info("Store entry " + id + " -- feed: " + entry.getFeedId());
|
||||
|
@ -108,23 +114,34 @@ public class StorageImplementation implements Storage {
|
|||
|
||||
if (entry == null)
|
||||
throw new StorageException("Entry is null");
|
||||
|
||||
if(entry.getId() == null)
|
||||
throw new StorageException("Entry id is null");
|
||||
if(entry.getFeedId() == null)
|
||||
throw new StorageException("feed id is null");
|
||||
if (LOG.isInfoEnabled())
|
||||
LOG.info("delete entry " + entry.getId() + " -- feed: "
|
||||
+ entry.getFeedId());
|
||||
StorageModifier modifier = this.controller.getStorageModifier();
|
||||
ReferenceCounter<StorageQuery> query = this.controller.getStorageQuery();
|
||||
// try to set concurrency Lock
|
||||
String key = entry.getId();
|
||||
setLock(key);
|
||||
try{
|
||||
if(query.get().isEntryStored(entry.getId(),entry.getFeedId())){
|
||||
|
||||
modifier.deleteEntry(new StorageEntryWrapper(entry,StorageOperation.DELETE));
|
||||
if(query.get().checkEntryVersion(entry.getId(),entry.getFeedId(),entry.getVersion())){
|
||||
modifier.deleteEntry(new StorageEntryWrapper(entry,StorageOperation.DELETE));
|
||||
}else
|
||||
throw new ModificationConflictException("The entry version does not match -- entry "+entry.getId()+" feed:"+entry.getFeedId()+" version: "+entry.getVersion());
|
||||
}
|
||||
else
|
||||
throw new ResourceNotFoundException("Entry for entry id: "+entry.getId()+" is not stored");
|
||||
}catch (IOException e) {
|
||||
throw new StorageException("Can not access storage");
|
||||
}finally{
|
||||
query.decrementRef();
|
||||
if(query != null)
|
||||
query.decrementRef();
|
||||
// release lock for concurrency
|
||||
releaseLock(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,6 +154,8 @@ public class StorageImplementation implements Storage {
|
|||
throw new StorageException("entry is null");
|
||||
if(entry.getId() == null)
|
||||
throw new StorageException("entry id is null");
|
||||
if(entry.getServiceConfig() == null)
|
||||
throw new StorageException("service config is not set -- null");
|
||||
if(entry.getFeedId() == null)
|
||||
throw new StorageException("feed id is null");
|
||||
if (LOG.isInfoEnabled())
|
||||
|
@ -144,28 +163,56 @@ public class StorageImplementation implements Storage {
|
|||
+ entry.getFeedId());
|
||||
StorageModifier modifier = this.controller.getStorageModifier();
|
||||
ReferenceCounter<StorageQuery> query = this.controller.getStorageQuery();
|
||||
// try to set concurrency Lock
|
||||
String key = entry.getId();
|
||||
setLock(key);
|
||||
try {
|
||||
StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,
|
||||
StorageOperation.UPDATE);
|
||||
if(query.get().isEntryStored(entry.getId(),entry.getFeedId()))
|
||||
modifier.updateEntry(wrapper);
|
||||
else
|
||||
|
||||
|
||||
if(query.get().isEntryStored(entry.getId(),entry.getFeedId())){
|
||||
|
||||
if(query.get().checkEntryVersion(entry.getId(),entry.getFeedId(),entry.getVersion())){
|
||||
entry.setVersion(entry.getVersion()+1);
|
||||
StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,
|
||||
StorageOperation.UPDATE);
|
||||
modifier.updateEntry(wrapper);
|
||||
}else
|
||||
throw new ModificationConflictException("The entry version does not match -- entry "+entry.getId()+" feed:"+entry.getFeedId()+" version: "+entry.getVersion());
|
||||
|
||||
}else
|
||||
throw new ResourceNotFoundException("Entry for entry id: "+entry.getId()+" is not stored");
|
||||
|
||||
} catch (IOException e) {
|
||||
LOG.error("Can't update entry for feedID: " + entry.getFeedId()
|
||||
+ "; entryId: " + entry.getId() + " -- " + e.getMessage(),
|
||||
e);
|
||||
StorageException ex = new StorageException("Can't create Entry -- "
|
||||
StorageException ex = new StorageException("Can't update Entry -- "
|
||||
+ e.getMessage(), e);
|
||||
ex.setStackTrace(e.getStackTrace());
|
||||
throw ex;
|
||||
|
||||
}
|
||||
|
||||
finally{
|
||||
if(query != null)
|
||||
query.decrementRef();
|
||||
// release lock for concurrency
|
||||
releaseLock(key);
|
||||
}
|
||||
|
||||
return entry.getEntry();
|
||||
|
||||
}
|
||||
private void setLock(String key) throws ModificationConflictException{
|
||||
if(!this.controller.getLock().setLock(key))
|
||||
throw new ModificationConflictException("Can not set lock for entry -- "+key);
|
||||
|
||||
}
|
||||
|
||||
private void releaseLock(String key) throws StorageException{
|
||||
if(!this.controller.getLock().releaseLock(key))
|
||||
throw new StorageException("Can not release lock for key: "+key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.Storage#getFeed(org.apache.lucene.gdata.data.ServerBaseFeed)
|
||||
|
@ -382,7 +429,7 @@ public class StorageImplementation implements Storage {
|
|||
throw ex;
|
||||
|
||||
} finally {
|
||||
if (query == null)
|
||||
if (query != null)
|
||||
query.decrementRef();
|
||||
}
|
||||
}
|
||||
|
@ -415,7 +462,7 @@ public class StorageImplementation implements Storage {
|
|||
throw ex;
|
||||
|
||||
} finally {
|
||||
if (query == null)
|
||||
if (query != null)
|
||||
query.decrementRef();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/**
|
||||
* 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;
|
||||
|
@ -9,7 +24,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
@ -67,13 +82,9 @@ public class StorageModifier {
|
|||
|
||||
private IndexModifier modifier;
|
||||
|
||||
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);
|
||||
private Lock lock = new ReentrantLock();
|
||||
|
||||
private final AtomicBoolean isClosed = new AtomicBoolean(false);
|
||||
|
||||
private final Lock readLock = this.lock.readLock();
|
||||
|
||||
private final Lock writeLock = this.lock.writeLock();
|
||||
|
||||
private final static int DEFAULT_OPTIMIZE_INTERVAL = 10;
|
||||
|
||||
|
@ -130,17 +141,33 @@ public class StorageModifier {
|
|||
throws StorageException {
|
||||
if(wrapper.getOperation() != StorageOperation.UPDATE)
|
||||
throw new StorageException("Illegal method call -- updateEntry does not accept other storageOperations than update");
|
||||
this.readLock.lock();
|
||||
this.lock.lock();
|
||||
try {
|
||||
|
||||
Term tempTerm = new Term(StorageEntryWrapper.FIELD_ENTRY_ID,
|
||||
wrapper.getEntryId());
|
||||
this.documentMap.put(wrapper.getEntryId(), wrapper
|
||||
.getLuceneDocument());
|
||||
this.deletedForUpdateDocumentQueue.add(tempTerm);
|
||||
this.buffer.addEntry(wrapper);
|
||||
storageModified();
|
||||
/*
|
||||
* If storage not written write entry to recoverfile
|
||||
* and make the entry available via the buffer
|
||||
*/
|
||||
if(this.modifiedCounter != 0)
|
||||
try{
|
||||
this.controller.writeRecoverEntry(wrapper);
|
||||
this.buffer.addEntry(wrapper);
|
||||
}catch (Exception e) {
|
||||
/*
|
||||
* remove from all resources
|
||||
*/
|
||||
this.documentMap.remove(wrapper.getEntryId());
|
||||
this.deletedForUpdateDocumentQueue.remove(tempTerm);
|
||||
|
||||
}
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,14 +183,27 @@ public class StorageModifier {
|
|||
throws StorageException {
|
||||
if(wrapper.getOperation() != StorageOperation.INSERT)
|
||||
throw new StorageException("Illegal method call -- insertEntry does not accept other storage operations than insert");
|
||||
this.readLock.lock();
|
||||
this.lock.lock();
|
||||
try {
|
||||
this.documentMap.put(wrapper.getEntryId(), wrapper
|
||||
.getLuceneDocument());
|
||||
this.buffer.addEntry(wrapper);
|
||||
storageModified();
|
||||
/*
|
||||
* If storage not written write entry to recoverfile
|
||||
* and make the entry available via the buffer
|
||||
*/
|
||||
if(this.modifiedCounter != 0)
|
||||
try{
|
||||
this.controller.writeRecoverEntry(wrapper);
|
||||
this.buffer.addEntry(wrapper);
|
||||
}catch (Exception e) {
|
||||
/*
|
||||
* remove from all resources
|
||||
*/
|
||||
this.documentMap.remove(wrapper.getEntryId());
|
||||
}
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,15 +219,30 @@ public class StorageModifier {
|
|||
throws StorageException {
|
||||
if(wrapper.getOperation() != StorageOperation.DELETE)
|
||||
throw new StorageException("Illegal method call -- insertEntry does not accept other storage operations than delete");
|
||||
this.readLock.lock();
|
||||
this.lock.lock();
|
||||
try {
|
||||
|
||||
Term tempTerm = new Term(StorageEntryWrapper.FIELD_ENTRY_ID,
|
||||
wrapper.getEntryId());
|
||||
this.deletedDocumentQueue.add(tempTerm);
|
||||
this.buffer.addDeleted(wrapper.getEntryId(), wrapper.getFeedId());
|
||||
storageModified();
|
||||
/*
|
||||
* If storage not written write entry to recoverfile
|
||||
* and make the entry available via the buffer
|
||||
*/
|
||||
if(this.modifiedCounter != 0)
|
||||
try{
|
||||
this.controller.writeRecoverEntry(wrapper);
|
||||
this.buffer.addDeleted(wrapper.getEntryId(), wrapper.getFeedId());
|
||||
}catch (Exception e) {
|
||||
/*
|
||||
* remove from all resources
|
||||
*/
|
||||
this.deletedDocumentQueue.remove(tempTerm);
|
||||
|
||||
}
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,12 +256,12 @@ public class StorageModifier {
|
|||
* if the feed can not be written
|
||||
*/
|
||||
public void createFeed(StorageFeedWrapper wrapper) throws StorageException {
|
||||
this.readLock.lock();
|
||||
this.lock.lock();
|
||||
try {
|
||||
this.forceWriteDocuments.add(wrapper.getLuceneDocument());
|
||||
storageModified();
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,12 +275,12 @@ public class StorageModifier {
|
|||
* if the user can not be persisted.
|
||||
*/
|
||||
public void createAccount(StorageAccountWrapper account) throws StorageException {
|
||||
this.readLock.lock();
|
||||
this.lock.lock();
|
||||
try {
|
||||
this.forceWriteDocuments.add(account.getLuceneDocument());
|
||||
storageModified();
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,14 +294,14 @@ public class StorageModifier {
|
|||
* If the user could not be deleted
|
||||
*/
|
||||
public void deleteAccount(String accountName) throws StorageException {
|
||||
this.readLock.lock();
|
||||
this.lock.lock();
|
||||
try {
|
||||
//TODO delete all feeds and entries of this account
|
||||
this.forceWriteTerms.add(new Term(
|
||||
StorageAccountWrapper.FIELD_ACCOUNTNAME, accountName));
|
||||
storageModified();
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,7 +316,7 @@ public class StorageModifier {
|
|||
*/
|
||||
public void updateAccount(final StorageAccountWrapper user)
|
||||
throws StorageException {
|
||||
this.readLock.lock();
|
||||
this.lock.lock();
|
||||
try {
|
||||
this.forceWriteTerms.add(new Term(
|
||||
StorageAccountWrapper.FIELD_ACCOUNTNAME, user.getUser()
|
||||
|
@ -269,7 +324,7 @@ public class StorageModifier {
|
|||
this.forceWriteDocuments.add(user.getLuceneDocument());
|
||||
storageModified();
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,14 +339,14 @@ public class StorageModifier {
|
|||
*/
|
||||
public void updateFeed(final StorageFeedWrapper wrapper)
|
||||
throws StorageException {
|
||||
this.readLock.lock();
|
||||
this.lock.lock();
|
||||
try {
|
||||
this.forceWriteTerms.add(new Term(StorageFeedWrapper.FIELD_FEED_ID,
|
||||
wrapper.getFeed().getId()));
|
||||
this.forceWriteDocuments.add(wrapper.getLuceneDocument());
|
||||
storageModified();
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,7 +360,7 @@ public class StorageModifier {
|
|||
* if the feed can not be deleted
|
||||
*/
|
||||
public void deleteFeed(final String feedId) throws StorageException {
|
||||
this.readLock.lock();
|
||||
this.lock.lock();
|
||||
try {
|
||||
this.deletedDocumentQueue.add(new Term(StorageEntryWrapper.FIELD_FEED_REFERENCE,feedId));
|
||||
this.forceWriteTerms.add(new Term(StorageFeedWrapper.FIELD_FEED_ID,
|
||||
|
@ -313,16 +368,14 @@ public class StorageModifier {
|
|||
|
||||
storageModified();
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void storageModified() throws StorageException {
|
||||
if(this.isClosed.get())
|
||||
throw new IllegalStateException("StorageModifier is already closed");
|
||||
this.readLock.unlock();
|
||||
this.writeLock.lock();
|
||||
|
||||
|
||||
try {
|
||||
if(this.isClosed.get())
|
||||
throw new IllegalStateException("StorageModifier is already closed");
|
||||
|
@ -343,18 +396,18 @@ public class StorageModifier {
|
|||
|
||||
LOG.error("Writing persistent index failed - Recovering", e);
|
||||
throw new StorageException("could not write to storage index -- "+e.getMessage(),e);
|
||||
|
||||
} finally {
|
||||
this.readLock.lock();
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected void forceWrite() throws IOException {
|
||||
/**
|
||||
* Persists all changes imediately
|
||||
* @throws IOException -- if an IO Exception occures
|
||||
*/
|
||||
public void forceWrite() throws IOException {
|
||||
if(this.isClosed.get())
|
||||
throw new IllegalStateException("StorageModifier is already closed");
|
||||
this.writeLock.lock();
|
||||
this.lock.lock();
|
||||
try {
|
||||
if (LOG.isInfoEnabled())
|
||||
LOG.info("ForceWrite called -- current modifiedCounter: "
|
||||
|
@ -363,12 +416,12 @@ public class StorageModifier {
|
|||
requestNewIndexModifier();
|
||||
this.modifiedCounter = 0;
|
||||
} finally {
|
||||
this.writeLock.unlock();
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void requestNewIndexModifier() throws IOException {
|
||||
|
||||
this.controller.registerNewRecoverWriter();
|
||||
this.controller.registerNewStorageQuery();
|
||||
this.buffer = this.controller.releaseNewStorageBuffer();
|
||||
this.modifier = this.controller.createIndexModifier();
|
||||
|
@ -435,7 +488,7 @@ public class StorageModifier {
|
|||
protected void close() throws IOException {
|
||||
if(this.isClosed.get())
|
||||
throw new IllegalStateException("StorageModifier is already closed");
|
||||
this.writeLock.lock();
|
||||
this.lock.lock();
|
||||
try {
|
||||
if(this.isClosed.get())
|
||||
throw new IllegalStateException("StorageModifier is already closed");
|
||||
|
@ -447,7 +500,7 @@ public class StorageModifier {
|
|||
writePersistentIndex(true);
|
||||
this.modifiedCounter = 0;
|
||||
} finally {
|
||||
this.writeLock.unlock();
|
||||
this.lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.lucene.gdata.storage.lucenestorage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
@ -25,6 +26,7 @@ import java.util.List;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.gdata.data.GDataAccount;
|
||||
import org.apache.lucene.gdata.server.GDataEntityBuilder;
|
||||
import org.apache.lucene.gdata.server.registry.ProvidedService;
|
||||
|
@ -66,6 +68,7 @@ import com.google.gdata.util.ParseException;
|
|||
*/
|
||||
public class StorageQuery {
|
||||
private static final Log LOG = LogFactory.getLog(StorageQuery.class);
|
||||
|
||||
private final StorageBuffer buffer;
|
||||
|
||||
private final Searcher searcher;
|
||||
|
@ -178,20 +181,19 @@ public class StorageQuery {
|
|||
@SuppressWarnings("unchecked")
|
||||
public BaseFeed getLatestFeedQuery(final String feedId,
|
||||
final int resultCount, final int startIndex,
|
||||
final ProvidedService config) throws IOException,
|
||||
ParseException {
|
||||
final ProvidedService config) throws IOException, ParseException {
|
||||
DateTime updated = null;
|
||||
Hits feedHits = storageFeedQuery(feedId);
|
||||
if(feedHits.length() == 0)
|
||||
if (feedHits.length() == 0)
|
||||
return null;
|
||||
BaseFeed retVal = buildFeedFromLuceneDocument(feedHits.doc(0),config);
|
||||
|
||||
BaseFeed retVal = buildFeedFromLuceneDocument(feedHits.doc(0), config);
|
||||
|
||||
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) {
|
||||
updated = bufferedWrapperList.get(0).getEntry().getUpdated();
|
||||
|
@ -199,14 +201,13 @@ public class StorageQuery {
|
|||
if ((bufferedWrapperList.size() - offset) > 0) {
|
||||
StorageEntryWrapper wrappedEntry = bufferedWrapperList
|
||||
.get(offset++);
|
||||
returnList
|
||||
.add(wrappedEntry.getEntry());
|
||||
returnList.add(wrappedEntry.getEntry());
|
||||
} else
|
||||
break;
|
||||
}
|
||||
// reset offset
|
||||
offset = startIndex - 1;
|
||||
if (alreadyAdded == resultCount){
|
||||
if (alreadyAdded == resultCount) {
|
||||
retVal.getEntries().addAll(returnList);
|
||||
retVal.setUpdated(updated);
|
||||
return retVal;
|
||||
|
@ -229,14 +230,17 @@ public class StorageQuery {
|
|||
BaseEntry entry = buildEntryFromLuceneDocument(doc, config);
|
||||
returnList.add(entry);
|
||||
}
|
||||
if(updated == null){
|
||||
try{
|
||||
long updatedTimeStamp = Long.parseLong(hits.doc(0).get(StorageEntryWrapper.FIELD_TIMESTAMP));
|
||||
updated = new DateTime(updatedTimeStamp);
|
||||
}catch (Exception e) {
|
||||
LOG.warn("could not create DateTime -- "+e.getMessage(),e);
|
||||
updated = buildEntryFromLuceneDocument(hits.doc(0),config).getUpdated();
|
||||
}
|
||||
if (updated == null) {
|
||||
try {
|
||||
long updatedTimeStamp = Long.parseLong(hits.doc(0).get(
|
||||
StorageEntryWrapper.FIELD_TIMESTAMP));
|
||||
updated = new DateTime(updatedTimeStamp);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("could not create DateTime -- " + e.getMessage(),
|
||||
e);
|
||||
updated = buildEntryFromLuceneDocument(hits.doc(0), config)
|
||||
.getUpdated();
|
||||
}
|
||||
}
|
||||
}
|
||||
retVal.setUpdated(updated);
|
||||
|
@ -351,21 +355,18 @@ public class StorageQuery {
|
|||
}
|
||||
|
||||
private BaseEntry buildEntryFromLuceneDocument(final Document doc,
|
||||
final ProvidedService config) throws ParseException,
|
||||
IOException {
|
||||
StringReader reader = new StringReader(doc.getField(
|
||||
StorageEntryWrapper.FIELD_CONTENT).stringValue());
|
||||
return GDataEntityBuilder.buildEntry( reader, config);
|
||||
final ProvidedService config) throws ParseException, IOException {
|
||||
Reader reader = new StringReader(doc.getField(StorageEntryWrapper.FIELD_CONTENT).stringValue());
|
||||
BaseEntry entry = GDataEntityBuilder.buildEntry(reader, config);
|
||||
entry.setVersionId(doc.getField(StorageEntryWrapper.FIELD_VERSION).stringValue());
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
private BaseFeed buildFeedFromLuceneDocument(final Document doc,
|
||||
final ProvidedService config) throws ParseException,
|
||||
IOException {
|
||||
StringReader reader = new StringReader(doc.getField(
|
||||
StorageFeedWrapper.FIELD_CONTENT).stringValue());
|
||||
return GDataEntityBuilder
|
||||
.buildFeed(reader, config);
|
||||
final ProvidedService config) throws ParseException, IOException {
|
||||
Reader reader = new StringReader(doc.getField(StorageFeedWrapper.FIELD_CONTENT).stringValue());
|
||||
return GDataEntityBuilder.buildFeed(reader, config);
|
||||
|
||||
}
|
||||
|
||||
|
@ -403,21 +404,28 @@ public class StorageQuery {
|
|||
|
||||
/**
|
||||
* Checks whether a feed for the given feedID is stored
|
||||
* @param feedId - the feed ID
|
||||
* @return <code>true</code> if and only if a feed is stored for the provided feed ID, <code>false</code> if no feed for the given id is stored
|
||||
*
|
||||
* @param feedId -
|
||||
* the feed ID
|
||||
* @return <code>true</code> if and only if a feed is stored for the
|
||||
* provided feed ID, <code>false</code> if no feed for the given
|
||||
* id is stored
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean isFeedStored(String feedId)throws IOException{
|
||||
public boolean isFeedStored(String feedId) throws IOException {
|
||||
Hits h = storageFeedQuery(feedId);
|
||||
return (h.length() > 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the feedtype for the given feed ID
|
||||
* @param feedID - the feed ID
|
||||
*
|
||||
* @param feedID -
|
||||
* the feed ID
|
||||
* @return - the feed type
|
||||
* @throws IOException - if the storage can not be accessed
|
||||
* @throws IOException -
|
||||
* if the storage can not be accessed
|
||||
*/
|
||||
public String getService(String feedID) throws IOException {
|
||||
Hits hits = storageFeedQuery(feedID);
|
||||
|
@ -427,6 +435,7 @@ public class StorageQuery {
|
|||
String feedType = doc.get(StorageFeedWrapper.FIELD_SERVICE_ID);
|
||||
return feedType;
|
||||
}
|
||||
|
||||
private Hits storageFeedQuery(String feedId) throws IOException {
|
||||
TermQuery query = new TermQuery(new Term(
|
||||
StorageFeedWrapper.FIELD_FEED_ID, feedId));
|
||||
|
@ -435,58 +444,103 @@ public class StorageQuery {
|
|||
|
||||
/**
|
||||
* Looks up the account reference for the given feed id
|
||||
* @param feedId - id of the feed
|
||||
* @return - the name of the account associated with the feed for the given feed id, or <code>null</code> if the feed is not stored
|
||||
* @throws IOException - if the storage can not be accessed
|
||||
*
|
||||
* @param feedId -
|
||||
* id of the feed
|
||||
* @return - the name of the account associated with the feed for the given
|
||||
* feed id, or <code>null</code> if the feed is not stored
|
||||
* @throws IOException -
|
||||
* if the storage can not be accessed
|
||||
*/
|
||||
public String getAccountNameForFeedId(String feedId) throws IOException {
|
||||
Hits h = storageFeedQuery(feedId);
|
||||
if(h.length() == 0)
|
||||
if (h.length() == 0)
|
||||
return null;
|
||||
Document doc = h.doc(0);
|
||||
return doc.get(StorageFeedWrapper.FIELD_ACCOUNTREFERENCE);
|
||||
|
||||
|
||||
}
|
||||
protected long getEntryLastModified(final String entryId,final String feedId) throws IOException, StorageException{
|
||||
StorageEntryWrapper wrapper = this.buffer.getEntry(entryId,feedId);
|
||||
if(wrapper != null)
|
||||
|
||||
protected long getEntryLastModified(final String entryId,
|
||||
final String feedId) throws IOException, StorageException {
|
||||
StorageEntryWrapper wrapper = this.buffer.getEntry(entryId, feedId);
|
||||
if (wrapper != null)
|
||||
return wrapper.getTimestamp();
|
||||
|
||||
|
||||
Hits h = storageQuery(entryId);
|
||||
if(h.length() > 0)
|
||||
try{
|
||||
return Long.parseLong(h.doc(0).get(StorageEntryWrapper.FIELD_TIMESTAMP));
|
||||
}catch (Exception e) {
|
||||
LOG.warn("Can not parse timestamp from entry -- "+h.doc(0).get(StorageEntryWrapper.FIELD_TIMESTAMP));
|
||||
if (h.length() > 0)
|
||||
try {
|
||||
return Long.parseLong(h.doc(0).get(
|
||||
StorageEntryWrapper.FIELD_TIMESTAMP));
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Can not parse timestamp from entry -- "
|
||||
+ h.doc(0).get(StorageEntryWrapper.FIELD_TIMESTAMP));
|
||||
}
|
||||
else
|
||||
else
|
||||
throw new StorageException("Entry not found");
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected long getFeedLastModified(final String feedId)throws IOException{
|
||||
|
||||
protected long getFeedLastModified(final String feedId) throws IOException {
|
||||
Long bufferedTime = this.buffer.getFeedLastModified(feedId);
|
||||
if(bufferedTime != null)
|
||||
if (bufferedTime != null)
|
||||
return bufferedTime;
|
||||
Hits entryHits = storageFeedQuery(feedId,this.timeStampSort);
|
||||
if(entryHits.length() > 0){
|
||||
try{
|
||||
return Long.parseLong(entryHits.doc(0).getField(StorageEntryWrapper.FIELD_TIMESTAMP).stringValue());
|
||||
}catch (Exception e) {
|
||||
LOG.warn("Can not parse timestamp from entry -- "+entryHits.doc(0).get(StorageEntryWrapper.FIELD_TIMESTAMP));
|
||||
Hits entryHits = storageFeedQuery(feedId, this.timeStampSort);
|
||||
if (entryHits.length() > 0) {
|
||||
try {
|
||||
return Long.parseLong(entryHits.doc(0).getField(
|
||||
StorageEntryWrapper.FIELD_TIMESTAMP).stringValue());
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Can not parse timestamp from entry -- "
|
||||
+ entryHits.doc(0).get(
|
||||
StorageEntryWrapper.FIELD_TIMESTAMP));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
protected boolean isEntryStored(String entryId,String feedId) throws IOException{
|
||||
if(this.buffer.getEntry(entryId,feedId)!=null)
|
||||
return true;
|
||||
|
||||
|
||||
protected boolean isEntryStored(String entryId, String feedId)
|
||||
throws IOException {
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Checking isEntryStored for entryid " + entryId
|
||||
+ " feedid: " + feedId);
|
||||
if (this.buffer.getEntry(entryId, feedId) != null)
|
||||
return true;
|
||||
|
||||
Hits h = storageQuery(entryId);
|
||||
if(h.length() > 0)
|
||||
if (h.length() > 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean checkEntryVersion(String id, String feedId, int version)
|
||||
throws IOException {
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Checking entry version for entryid " + id + " feedid: "
|
||||
+ feedId + " version: " + version);
|
||||
StorageEntryWrapper wrapper = this.buffer.getEntry(id, feedId);
|
||||
|
||||
if (wrapper != null)
|
||||
return wrapper.getVersion() == version;
|
||||
|
||||
Hits h = storageQuery(id);
|
||||
if (h.length() < 1)
|
||||
return false;
|
||||
Document doc = h.doc(0);
|
||||
String fieldValue = null;
|
||||
try {
|
||||
fieldValue = doc.getField(StorageEntryWrapper.FIELD_VERSION)
|
||||
.stringValue();
|
||||
int storedVersion = Integer.parseInt(fieldValue);
|
||||
if(LOG.isDebugEnabled())
|
||||
LOG.debug("StoredEntry has version "+storedVersion +" return compare result");
|
||||
return storedVersion == version;
|
||||
} catch (Exception e) {
|
||||
LOG.error("Entry has no parable Version id or field is not set -- "
|
||||
+ fieldValue);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,18 +60,29 @@ public class RecoverController {
|
|||
private final boolean recover;
|
||||
private final boolean keepRecoverFiles;
|
||||
|
||||
/**
|
||||
* @param recoverDirectory
|
||||
* @param recover
|
||||
* @param keepRecoverFiles
|
||||
*/
|
||||
public RecoverController(final File recoverDirectory, boolean recover, boolean keepRecoverFiles) {
|
||||
if (recoverDirectory == null)
|
||||
throw new IllegalArgumentException("directory must not be null");
|
||||
if(!recoverDirectory.exists())
|
||||
recoverDirectory.mkdirs();
|
||||
if (!recoverDirectory.isDirectory())
|
||||
throw new IllegalStateException("the given File is not a directory");
|
||||
throw new IllegalStateException("the given File is not a directory -- "+recoverDirectory);
|
||||
this.recover = recover;
|
||||
this.keepRecoverFiles = keepRecoverFiles;
|
||||
this.recoverDirectory = recoverDirectory;
|
||||
|
||||
}
|
||||
|
||||
public void storageModified(StorageEntryWrapper wrapper)
|
||||
/**
|
||||
* @param wrapper
|
||||
* @throws RecoverException
|
||||
*/
|
||||
public void storageModified(StorageEntryWrapper wrapper)
|
||||
throws RecoverException {
|
||||
// prevent deadlock either recovering or writing
|
||||
if(this.recover){
|
||||
|
@ -92,6 +103,9 @@ public class RecoverController {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param modifier
|
||||
*/
|
||||
public void recoverEntries(final StorageModifier modifier){
|
||||
// prevent deadlock either recovering or writing
|
||||
if(!this.recover){
|
||||
|
@ -105,14 +119,17 @@ public class RecoverController {
|
|||
for (int i = 0; i < files.length; i++) {
|
||||
if(!files[i].isDirectory()){
|
||||
try{
|
||||
LOG.info("Recover file -- "+files[i]);
|
||||
this.fileReader = new BufferedReader(new FileReader(files[i]));
|
||||
List<StorageEntryWrapper> entryList = this.reader.recoverEntries(this.fileReader);
|
||||
if(entryList.size() == 0)
|
||||
continue;
|
||||
storeEntries(entryList,modifier);
|
||||
this.fileReader.close();
|
||||
if(!this.keepRecoverFiles)
|
||||
if(!this.keepRecoverFiles){
|
||||
LOG.info("Recovering file -- "+files[i]+" successful, delete file");
|
||||
files[i].delete();
|
||||
}
|
||||
}catch (StorageException e) {
|
||||
LOG.error("Can't store recover entries for file: "+files[i].getName()+" -- keep file "+e.getMessage(),e);
|
||||
}catch (IOException e) {
|
||||
|
@ -126,7 +143,7 @@ public class RecoverController {
|
|||
}
|
||||
}
|
||||
|
||||
protected void storeEntries(final List<StorageEntryWrapper> entries, final StorageModifier modifier) throws StorageException{
|
||||
protected void storeEntries(final List<StorageEntryWrapper> entries, final StorageModifier modifier) throws StorageException, IOException{
|
||||
for (StorageEntryWrapper wrapper : entries) {
|
||||
if(wrapper.getOperation() == StorageOperation.DELETE)
|
||||
modifier.deleteEntry(wrapper);
|
||||
|
@ -134,12 +151,15 @@ public class RecoverController {
|
|||
modifier.insertEntry(wrapper);
|
||||
else if(wrapper.getOperation() == StorageOperation.UPDATE)
|
||||
modifier.updateEntry(wrapper);
|
||||
|
||||
|
||||
modifier.forceWrite();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized void initialize() throws IOException {
|
||||
/**
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized void initialize() throws IOException {
|
||||
if(this.recover)
|
||||
return;
|
||||
String filename = System.currentTimeMillis() + FILE_SUFFIX;
|
||||
|
@ -150,12 +170,18 @@ public class RecoverController {
|
|||
|
||||
}
|
||||
|
||||
protected void destroy() throws RecoverException {
|
||||
/**
|
||||
* @throws RecoverException
|
||||
*/
|
||||
public synchronized void destroy() throws RecoverException {
|
||||
if (this.fileWriter != null) {
|
||||
this.lock.lock();
|
||||
try {
|
||||
|
||||
this.fileWriter.flush();
|
||||
this.fileWriter.close();
|
||||
if(!this.keepRecoverFiles && this.currentRecoverFile != null)
|
||||
this.currentRecoverFile.delete();
|
||||
} catch (IOException e) {
|
||||
throw new RecoverException("Can't close recover writer ", e);
|
||||
} finally {
|
||||
|
@ -163,6 +189,14 @@ public class RecoverController {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the RecoverController is initialized in recover mode, otherwise <code>false</code>
|
||||
*/
|
||||
public boolean isRecovering() {
|
||||
|
||||
return this.recover;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
|
||||
package org.apache.lucene.gdata.storage.lucenestorage.recover;
|
||||
|
||||
import org.apache.lucene.gdata.storage.StorageException;
|
||||
|
||||
/**
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public class RecoverException extends Exception {
|
||||
public class RecoverException extends StorageException {
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -140,24 +140,24 @@ public class RecoverReader {
|
|||
throw new RecoverException("Illegal metadata --- "+recoverString);
|
||||
temp = tokenizer.nextToken();
|
||||
if(temp == null)
|
||||
throw new RecoverException("Can't recover feed Id -- "+temp);
|
||||
throw new RecoverException("Can't recover feed Id -- is null");
|
||||
this.feedId = temp;
|
||||
temp = tokenizer.nextToken();
|
||||
if(temp == null)
|
||||
throw new RecoverException("Can't recover entry Id -- "+temp);
|
||||
throw new RecoverException("Can't recover entry Id -- is null");
|
||||
this.entryId = temp;
|
||||
|
||||
temp = tokenizer.nextToken();
|
||||
try{
|
||||
this.timestamp = Long.parseLong(temp);
|
||||
}catch (Exception e) {
|
||||
throw new RecoverException("Can't recover timestamp -- "+temp,e);
|
||||
throw new RecoverException("Can't recover timestamp -- is null",e);
|
||||
}
|
||||
|
||||
if(this.operation != StorageOperation.DELETE){
|
||||
temp = tokenizer.nextToken();
|
||||
if(temp == null)
|
||||
throw new RecoverException("Can't recover service -- "+temp);
|
||||
throw new RecoverException("Can't recover service -- is null");
|
||||
if(!GDataServerRegistry.getRegistry().isServiceRegistered(temp))
|
||||
throw new RecoverException("Service in recover metadata is not registered - "+temp);
|
||||
this.config = GDataServerRegistry.getRegistry().getProvidedService(temp);
|
||||
|
|
|
@ -65,6 +65,7 @@ public class RecoverWriter {
|
|||
writer.write(META_DATA_ENTRY_SEPARATOR);
|
||||
writer.write(STORAGE_OPERATION_SEPARATOR);
|
||||
writer.write(META_DATA_ENTRY_SEPARATOR);
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,21 +40,21 @@ import java.util.Stack;
|
|||
*/
|
||||
public class DateFormater {
|
||||
private final Stack<SimpleDateFormat> objectStack = new Stack<SimpleDateFormat>();
|
||||
|
||||
|
||||
private static final DateFormater formater = new DateFormater();
|
||||
|
||||
/**
|
||||
* Date format as it is used in Http Last modified header (Tue, 15 Nov 1994
|
||||
* 12:45:26 GMT)
|
||||
*/
|
||||
public static String HTTP_HEADER_DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss z";
|
||||
public final static String HTTP_HEADER_DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss z";
|
||||
/**
|
||||
* Date format as it is used in Http Last modified header (Tue, 15 Nov 1994
|
||||
* 12:45:26 +0000)
|
||||
*/
|
||||
public static String HTTP_HEADER_DATE_FORMAT_TIME_OFFSET = "EEE, d MMM yyyy HH:mm:ss Z";
|
||||
public final static String HTTP_HEADER_DATE_FORMAT_TIME_OFFSET = "EEE, d MMM yyyy HH:mm:ss Z";
|
||||
|
||||
private DateFormater() {
|
||||
protected DateFormater() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
@ -74,8 +74,11 @@ public class DateFormater {
|
|||
"given parameters must not be null");
|
||||
SimpleDateFormat inst = formater.getFormater();
|
||||
inst.applyPattern(format);
|
||||
formater.returnFomater(inst);
|
||||
return inst.format(date);
|
||||
try{
|
||||
return inst.format(date);
|
||||
}finally{
|
||||
formater.returnFomater(inst);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Parses the given string into one of the specified formates
|
||||
|
@ -109,19 +112,26 @@ public class DateFormater {
|
|||
"given parameters must not be null");
|
||||
|
||||
SimpleDateFormat inst = formater.getFormater();
|
||||
try{
|
||||
inst.applyPattern(pattern);
|
||||
return inst.parse(dateString);
|
||||
}finally{
|
||||
formater.returnFomater(inst);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private SimpleDateFormat getFormater() {
|
||||
protected SimpleDateFormat getFormater() {
|
||||
if (this.objectStack.empty())
|
||||
return new SimpleDateFormat(DateFormater.HTTP_HEADER_DATE_FORMAT,Locale.ENGLISH);
|
||||
return this.objectStack.pop();
|
||||
|
||||
}
|
||||
|
||||
private void returnFomater(final SimpleDateFormat format) {
|
||||
protected void returnFomater(final SimpleDateFormat format) {
|
||||
if (this.objectStack.size() <= 25)
|
||||
this.objectStack.push(format);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* 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.utils;
|
||||
|
||||
/**
|
||||
* Basic interface to be implemented by ObjectPool implementations. Pools should
|
||||
* provide a constructor with a
|
||||
* {@link org.apache.lucene.gdata.utils.PoolObjectFactory} as a mandatory
|
||||
* parameter to create and destory the pooled objects.
|
||||
*
|
||||
* @see org.apache.lucene.gdata.utils.PoolObjectFactory
|
||||
*
|
||||
* @author Simon Willnauer
|
||||
* @param <Type> -
|
||||
* the type of the pooled objects
|
||||
*
|
||||
*/
|
||||
public interface Pool<Type> {
|
||||
/**
|
||||
* Return an object from the pool or create one if the pool is empty.
|
||||
*
|
||||
* @return - a pooled object
|
||||
*/
|
||||
public abstract Type aquire();
|
||||
|
||||
/**
|
||||
* Adds a previously aquired object to the pool. If the pool has already
|
||||
* been closed or if the pool has already reached his size the released
|
||||
* object will be destroyed using
|
||||
* {@link PoolObjectFactory#destroyInstance(Object)} method.
|
||||
*
|
||||
* @param type -
|
||||
* the previously aquired object
|
||||
*/
|
||||
public abstract void release(final Type type);
|
||||
|
||||
/**
|
||||
* @return - the defined size of the pool
|
||||
*/
|
||||
public abstract int getSize();
|
||||
|
||||
/**
|
||||
* @return - the expire time of the objects in the pool if defined
|
||||
*/
|
||||
public abstract long getExpireTime();
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if and only if the pool uses an expire
|
||||
* mechanismn, otherwith <code>false</code>
|
||||
*/
|
||||
public abstract boolean expires();
|
||||
|
||||
/**
|
||||
* releases all pooled objects using
|
||||
* {@link PoolObjectFactory#destroyInstance(Object)} method. The pool can not
|
||||
* be reused after this method has been called
|
||||
*/
|
||||
public abstract void destroy();
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* 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.utils;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This interface enables {@link org.apache.lucene.gdata.utils.Pool} users to
|
||||
* build a custom creation and destroy mechanismn for pooled objects.
|
||||
* Implementations can use standart creation to prevent the pool from using
|
||||
* reflection to create objects of the specific type. This implementation
|
||||
* seperates the Pool implementation from the creation or the destruction of a
|
||||
* pooled type.
|
||||
* </p>
|
||||
* <p>
|
||||
* The destroy method can be used to close datasource connections or release
|
||||
* resources if the object will be removed from the pool
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @see org.apache.lucene.gdata.utils.Pool
|
||||
* @author Simon Willnauer
|
||||
* @param <Type> -
|
||||
* the type to be created
|
||||
*
|
||||
*/
|
||||
public interface PoolObjectFactory<Type> {
|
||||
|
||||
/**
|
||||
* @return an instance of the specified Type
|
||||
*/
|
||||
public abstract Type getInstance();
|
||||
|
||||
/**
|
||||
* destroys the given instance
|
||||
* @param type - the object to destroy / release all resources
|
||||
*/
|
||||
public abstract void destroyInstance(Type type);
|
||||
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/**
|
||||
* 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.utils;
|
||||
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* A Simple implementation of the {@link org.apache.lucene.gdata.utils.Pool}
|
||||
* interface using a {@link java.util.Stack} as a buffer for the pooled objects.
|
||||
* This implementation does not provide any timeout mechanismn. Objects will
|
||||
* stay inside the pool until the pool is destroyed.
|
||||
* <p>
|
||||
* If any object will be released e.g. handover to the pool and the pool has
|
||||
* already enought objects in the pool the released object will be destroyed. If
|
||||
* the pool is empty a new Object will be created.
|
||||
* </p>
|
||||
* <p>
|
||||
* This implementation does not track any references to the objects aquired by
|
||||
* any other resource. The objects must be destroyed manually if not released to
|
||||
* the pool after aquired.
|
||||
* </p>
|
||||
*
|
||||
* @author Simon Willnauer
|
||||
* @param <Type>
|
||||
*
|
||||
*/
|
||||
public class SimpleObjectPool<Type> implements Pool<Type> {
|
||||
private static final Log LOG = LogFactory.getLog(SimpleObjectPool.class);
|
||||
private volatile boolean isDestroyed = false;
|
||||
|
||||
private final PoolObjectFactory<Type> factory;
|
||||
|
||||
static final int DEFAULTSIZE = 5;
|
||||
static final int MINIMALSIZE = 1;
|
||||
|
||||
private final int size;
|
||||
|
||||
private final Stack<Type> pool;
|
||||
|
||||
private final ReentrantReadWriteLock masterLock = new ReentrantReadWriteLock();
|
||||
|
||||
private final Lock readLock = this.masterLock.readLock();
|
||||
|
||||
private final Lock writeLock = this.masterLock.writeLock();
|
||||
|
||||
/**
|
||||
* Constructs a new {@link SimpleObjectPool} and sets the ObjectFactory and the pool size
|
||||
* @param size - the maximum size of the pool
|
||||
* @param factory - factory to create and destroy pooled objects
|
||||
*
|
||||
*/
|
||||
public SimpleObjectPool(int size, PoolObjectFactory<Type> factory) {
|
||||
if (factory == null)
|
||||
throw new IllegalArgumentException("Factory must not be null");
|
||||
this.factory = factory;
|
||||
this.size = size < MINIMALSIZE ? MINIMALSIZE : size;
|
||||
this.pool = new Stack<Type>();
|
||||
for (int i = 0; i < this.size; i++) {
|
||||
this.pool.push(this.factory.getInstance());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param factory
|
||||
*/
|
||||
public SimpleObjectPool(PoolObjectFactory<Type> factory) {
|
||||
this(DEFAULTSIZE,factory);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.utils.Pool#aquire()
|
||||
*/
|
||||
public Type aquire() {
|
||||
// fail if writelock is aquired
|
||||
if (this.readLock.tryLock()) {
|
||||
try {
|
||||
if (this.isDestroyed)
|
||||
throw new IllegalStateException(
|
||||
"The pool has already been closed");
|
||||
if (this.pool.isEmpty())
|
||||
return this.factory.getInstance();
|
||||
return this.pool.pop();
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("The pool has already been closed");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type - generic type
|
||||
* @see org.apache.lucene.gdata.utils.Pool#release(Object)
|
||||
*/
|
||||
public void release(Type type) {
|
||||
// fail if writelock is aquired
|
||||
if (this.readLock.tryLock()) {
|
||||
try {
|
||||
if (this.pool.size() < this.size && !this.isDestroyed)
|
||||
this.pool.push(type);
|
||||
else
|
||||
this.factory.destroyInstance(type);
|
||||
} finally {
|
||||
this.readLock.unlock();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// enable object need to be destoryed
|
||||
this.factory.destroyInstance(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.utils.Pool#getSize()
|
||||
*/
|
||||
public int getSize() {
|
||||
|
||||
return this.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.utils.Pool#getExpireTime()
|
||||
*/
|
||||
public long getExpireTime() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.utils.Pool#expires()
|
||||
*/
|
||||
public boolean expires() {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.utils.Pool#destroy()
|
||||
*/
|
||||
public void destroy() {
|
||||
this.writeLock.lock();
|
||||
try {
|
||||
if (this.isDestroyed)
|
||||
return;
|
||||
this.isDestroyed = true;
|
||||
LOG.info("Destroy all elements in the pool -- poolsize: "+this.pool.size());
|
||||
for (Type type : this.pool) {
|
||||
this.factory.destroyInstance(type);
|
||||
}
|
||||
this.pool.clear();
|
||||
} finally {
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* 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.utils;
|
||||
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
/**
|
||||
* For use with Digester to throw exceptions on errors
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public final class SimpleSaxErrorHandler implements ErrorHandler{
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
|
||||
*/
|
||||
public void warning(SAXParseException arg0) throws SAXException {
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
|
||||
*/
|
||||
public void error(SAXParseException arg0) throws SAXException {
|
||||
|
||||
throw new SAXException("ERROR: Can not parse XML Document -- "+arg0.getMessage(),arg0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
|
||||
*/
|
||||
public void fatalError(SAXParseException arg0) throws SAXException {
|
||||
throw new SAXException("FATAL ERROR: Can not parse XML Document -- "+arg0.getMessage(),arg0);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="password">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:minLength value="5" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:element>
|
||||
<xs:element name="account-name">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:whiteSpace value="collapse" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="email-address" type="xs:string" />
|
||||
<xs:element name="url" type="xs:anyURI" />
|
||||
<xs:element name="name" type="xs:string" />
|
||||
<xs:element name="account-role">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:positiveInteger">
|
||||
<xs:fractionDigits value="2" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:element>
|
||||
|
||||
|
||||
<xs:element name="account-owner">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="name" />
|
||||
<xs:element ref="email-address" />
|
||||
<xs:element ref="url" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="account">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="account-name" />
|
||||
<xs:element ref="password" />
|
||||
<xs:element ref="account-role" />
|
||||
<xs:element ref="account-owner" minOccurs="0" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
|
@ -1,35 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gdata>
|
||||
<service name="feed" public="true">
|
||||
<feed-class>com.google.gdata.data.Feed</feed-class>
|
||||
<entry-class>com.google.gdata.data.Entry</entry-class>
|
||||
<extension-profile>
|
||||
com.google.gdata.data.ExtensionProfile
|
||||
</extension-profile>
|
||||
</service>
|
||||
<service name="calendar" public="true">
|
||||
<feed-class>
|
||||
com.google.gdata.data.extensions.EventFeed
|
||||
</feed-class>
|
||||
<entry-class>
|
||||
com.google.gdata.data.extensions.EventEntry
|
||||
</entry-class>
|
||||
<extension-profile>
|
||||
com.google.gdata.data.ExtensionProfile
|
||||
</extension-profile>
|
||||
</service>
|
||||
<server-components>
|
||||
<component>
|
||||
org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController
|
||||
</component>
|
||||
<component>
|
||||
org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory
|
||||
</component>
|
||||
<component>
|
||||
org.apache.lucene.gdata.server.ServiceFactory
|
||||
</component>
|
||||
<component>
|
||||
org.apache.lucene.gdata.server.authentication.BlowfishAuthenticationController
|
||||
</component>
|
||||
</server-components>
|
||||
</gdata>
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
|
||||
<properties>
|
||||
<comment>Lucene Storage Properties</comment>
|
||||
<entry key="gdata.server.storage.lucene.buffersize">20</entry>
|
||||
<entry key="gdata.server.storage.lucene.optimizeInterval">20</entry>
|
||||
<entry key="gdata.server.storage.lucene.persistFactor">20</entry>
|
||||
<entry key="gdata.server.storage.lucene.directory.ramDirectory">true</entry>
|
||||
<entry key="gdata.server.storage.lucene.directory">/tmp/storage/</entry>
|
||||
<entry key="gdata.server.storage.lucene.recover">true</entry>
|
||||
<entry key="gdata.server.storage.lucene.recover.keepFiles">false</entry>
|
||||
</properties>
|
|
@ -1,5 +1,8 @@
|
|||
package org.apache.lucene.gdata.data;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
@ -59,6 +62,7 @@ public class TestGDataUser extends TestCase {
|
|||
assertEquals(4,this.user.getRoles().size());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
*/
|
||||
package org.apache.lucene.gdata.server;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
@ -39,17 +42,15 @@ public class TestGDataRequest extends TestCase {
|
|||
private MockControl control;
|
||||
|
||||
private GDataRequest feedRequest;
|
||||
static{
|
||||
try {
|
||||
GDataServerRegistry.getRegistry().registerComponent(StorageStub.class);
|
||||
} catch (RegistryException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
protected void setUp() throws Exception {
|
||||
try{
|
||||
GDataServerRegistry.getRegistry().registerComponent(StorageStub.class,null);
|
||||
}catch (Exception e) {
|
||||
|
||||
}
|
||||
ProvidedService configurator = new ProvidedServiceStub();
|
||||
GDataServerRegistry.getRegistry().registerService(configurator);
|
||||
|
||||
|
@ -225,7 +226,7 @@ public class TestGDataRequest extends TestCase {
|
|||
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.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"),
|
||||
|
@ -235,7 +236,6 @@ public class TestGDataRequest extends TestCase {
|
|||
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();
|
||||
|
||||
|
@ -354,67 +354,95 @@ public class TestGDataRequest extends TestCase {
|
|||
this.control.replay();
|
||||
assertEquals("bla",this.feedRequest.getAuthToken());
|
||||
this.control.verify();
|
||||
this.control.reset();
|
||||
|
||||
}
|
||||
|
||||
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.getRequestURI(),"/feed/");
|
||||
// this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/");
|
||||
// this.control.expectAndReturn(this.request.getParameter("max-results"),"25",2);
|
||||
// this.control.expectAndReturn(this.request.getParameter("start-index"),null);
|
||||
// this.control.expectAndDefaultReturn(this.request.getParameter("alt"),
|
||||
// null);
|
||||
// this.control.expectAndDefaultReturn(this.request.getQueryString(),
|
||||
// queryString);
|
||||
// this.control.replay();
|
||||
// this.feedRequest.initializeRequest();
|
||||
// String nextID = "http://"+host+"/feed/"+queryString+startIndex;
|
||||
//
|
||||
// assertEquals("Next ID",nextID,this.feedRequest.getNextId());
|
||||
// this.control.reset();
|
||||
String host = "www.apache.org";
|
||||
String feedAndEntryID = "/feed/entryid";
|
||||
String queryString = "?max-results=25";
|
||||
String startIndex = "&start-index=26";
|
||||
Enumeration enu = new StringTokenizer("max-results",",");
|
||||
|
||||
|
||||
this.control.expectAndDefaultReturn(this.request.getParameterNames(),enu);
|
||||
this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host);
|
||||
this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/feed/");
|
||||
this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/");
|
||||
this.control.expectAndReturn(this.request.getParameter("max-results"),"25",4);
|
||||
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.verify();
|
||||
this.control.reset();
|
||||
|
||||
enu = new StringTokenizer("alt,max-results,start-index",",");
|
||||
queryString = "?alt=rss&max-results=25";
|
||||
|
||||
// queryString = "?alt=rss&max-results=25";
|
||||
//
|
||||
// this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host);
|
||||
// this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/feed/");
|
||||
// this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/");
|
||||
// this.control.expectAndReturn(this.request.getParameter("max-results"),"25",2);
|
||||
// this.control.expectAndReturn(this.request.getParameter("start-index"),"26",2);
|
||||
// this.control.expectAndDefaultReturn(this.request.getParameter("alt"),
|
||||
// null);
|
||||
// this.control.expectAndDefaultReturn(this.request.getQueryString(),
|
||||
// queryString+startIndex);
|
||||
// Enumeration e =
|
||||
// this.control.expectAndDefaultReturn(this.request.getParameterNames(),)
|
||||
//
|
||||
//
|
||||
// this.control.replay();
|
||||
// this.feedRequest.initializeRequest();
|
||||
// startIndex = "&start-index=51";
|
||||
// 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();
|
||||
// String selfID = "http://"+host+"/feed"+"?max-results=25";
|
||||
//
|
||||
// assertEquals("Self ID",selfID,this.feedRequest.getSelfId());
|
||||
// this.control.reset();
|
||||
this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host);
|
||||
this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/feed/");
|
||||
this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/");
|
||||
this.control.expectAndReturn(this.request.getParameter("max-results"),"25",4);
|
||||
this.control.expectAndReturn(this.request.getParameter("start-index"),"26",4);
|
||||
this.control.expectAndDefaultReturn(this.request.getParameter("alt"),
|
||||
"rss");
|
||||
this.control.expectAndDefaultReturn(this.request.getQueryString(),
|
||||
queryString+startIndex);
|
||||
|
||||
this.control.expectAndDefaultReturn(this.request.getParameterNames(),enu);
|
||||
|
||||
|
||||
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.getRequestURI(),"/feed/");
|
||||
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();
|
||||
String selfID = "http://"+host+"/feed"+"?max-results=25";
|
||||
|
||||
assertEquals("Self ID",selfID,this.feedRequest.getSelfId());
|
||||
this.control.reset();
|
||||
}
|
||||
|
||||
public void testGetContextPath(){
|
||||
String host = "www.apache.org";
|
||||
this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host);
|
||||
this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/feed/id/");
|
||||
this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/id/");
|
||||
this.control.replay();
|
||||
String result = "http://"+host+"/feed/id/";
|
||||
assertEquals(result,this.feedRequest.getContextPath());
|
||||
this.control.verify();
|
||||
this.control.reset();
|
||||
this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host);
|
||||
this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/feed/id");
|
||||
this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/id");
|
||||
this.control.replay();
|
||||
|
||||
assertEquals(result,this.feedRequest.getContextPath());
|
||||
this.control.verify();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import org.xml.sax.SAXException;
|
|||
public class TestAccountBuilder extends TestCase {
|
||||
private StringReader reader;
|
||||
private String inputXML;
|
||||
private StringReader invalidReader;
|
||||
private String invalidInputXML;
|
||||
protected void setUp() throws Exception {
|
||||
this.inputXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<account>" +
|
||||
|
@ -27,6 +29,18 @@ public class TestAccountBuilder extends TestCase {
|
|||
"</account>";
|
||||
|
||||
this.reader = new StringReader(this.inputXML);
|
||||
this.invalidInputXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<account>" +
|
||||
"<account-name>simon</account-name>" +
|
||||
"<account-role>6</account-role>" +
|
||||
"<account-owner>" +
|
||||
"<name>simon willnauer</name>" +
|
||||
"<email-address>simon@gmail.com</email-address>" +
|
||||
"<url>http://www.javawithchopsticks.de</url>" +
|
||||
"</account-owner>" +
|
||||
"</account>";
|
||||
|
||||
this.invalidReader = new StringReader(this.invalidInputXML);
|
||||
|
||||
}
|
||||
|
||||
|
@ -50,5 +64,14 @@ public class TestAccountBuilder extends TestCase {
|
|||
assertFalse(user.isUserInRole(AccountRole.USERADMINISTRATOR));
|
||||
|
||||
}
|
||||
|
||||
public void testBuildUserWrongXML() throws IOException{
|
||||
try{
|
||||
AccountBuilder.buildAccount(this.invalidReader);
|
||||
fail("invalid xml");
|
||||
}catch (SAXException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ public class TestBlowfishAuthenticationController extends TestCase {
|
|||
}catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
this.controller.setMinuteOffset(0);
|
||||
this.controller.setLoginTimeout(0);
|
||||
assertFalse(this.controller.authenticateToken(token,this.clientIp,AccountRole.ENTRYAMINISTRATOR,this.accountName));
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package org.apache.lucene.gdata.server.registry;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.lucene.gdata.server.ServiceFactory;
|
||||
import org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory;
|
||||
import org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory;
|
||||
|
@ -22,111 +24,130 @@ import org.apache.lucene.gdata.storage.StorageController;
|
|||
import org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController;
|
||||
|
||||
import com.google.gdata.data.Entry;
|
||||
import com.google.gdata.data.ExtensionProfile;
|
||||
import com.google.gdata.data.Feed;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class TestFeedRegistry extends TestCase {
|
||||
private GDataServerRegistry reg;
|
||||
private ProvidedServiceConfig configurator;
|
||||
@Override
|
||||
protected void setUp(){
|
||||
this.reg = GDataServerRegistry.getRegistry();
|
||||
this.configurator = new ProvidedServiceConfig();
|
||||
private GDataServerRegistry reg;
|
||||
|
||||
private ProvidedServiceConfig configurator;
|
||||
|
||||
@Override
|
||||
protected void setUp() {
|
||||
this.reg = GDataServerRegistry.getRegistry();
|
||||
this.configurator = new ProvidedServiceConfig();
|
||||
this.configurator.setEntryType(Entry.class);
|
||||
this.configurator.setFeedType(Feed.class);
|
||||
}
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
this.configurator.setExtensionProfile(new ExtensionProfile());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.registerFeed(FeedInstanceConfigurator)'
|
||||
*/
|
||||
public void testRegisterService() {
|
||||
String service = "service";
|
||||
registerService(service);
|
||||
assertEquals("Registered Configurator",this.configurator,this.reg.getProvidedService(service));
|
||||
assertNull("not registered Configurator",this.reg.getProvidedService("something"));
|
||||
try{
|
||||
this.reg.getProvidedService(null);
|
||||
fail("Exception expected");
|
||||
}catch (IllegalArgumentException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @see junit.framework.TestCase#tearDown()
|
||||
*/
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
this.reg.flushRegistry();
|
||||
|
||||
/**
|
||||
* Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getFeedConfigurator(String)'
|
||||
*/
|
||||
public void testFlushRegistry() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 testRegisterService() {
|
||||
String service = "service";
|
||||
registerService(service);
|
||||
|
||||
assertEquals("Registered Configurator",this.configurator,this.reg.getProvidedService(service));
|
||||
this.reg.flushRegistry();
|
||||
assertNull("Registry flushed",this.reg.getProvidedService(service));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void testIsFeedRegistered(){
|
||||
String service = "service";
|
||||
registerService(service);
|
||||
assertTrue("Feed is registerd",this.reg.isServiceRegistered(service));
|
||||
assertFalse("null Feed is not registerd",this.reg.isServiceRegistered(null));
|
||||
assertFalse("Feed is not registerd",this.reg.isServiceRegistered("something"));
|
||||
|
||||
}
|
||||
|
||||
private void registerService(String servicename){
|
||||
|
||||
this.configurator.setName(servicename);
|
||||
this.reg.registerService(this.configurator);
|
||||
}
|
||||
|
||||
public void testRegisterComponent() throws RegistryException{
|
||||
assertEquals("Registered Configurator", this.configurator, this.reg
|
||||
.getProvidedService(service));
|
||||
assertNull("not registered Configurator", this.reg
|
||||
.getProvidedService("something"));
|
||||
try {
|
||||
this.reg.registerComponent(StorageController.class);
|
||||
this.reg.getProvidedService(null);
|
||||
fail("Exception expected");
|
||||
} catch (IllegalArgumentException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.server.registry.FeedRegistry.getFeedConfigurator(String)'
|
||||
*/
|
||||
public void testFlushRegistry() {
|
||||
String service = "service";
|
||||
registerService(service);
|
||||
|
||||
assertEquals("Registered Configurator", this.configurator, this.reg
|
||||
.getProvidedService(service));
|
||||
this.reg.flushRegistry();
|
||||
assertNull("Registry flushed", this.reg.getProvidedService(service));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void testIsFeedRegistered() {
|
||||
String service = "service";
|
||||
registerService(service);
|
||||
assertTrue("Feed is registerd", this.reg.isServiceRegistered(service));
|
||||
assertFalse("null Feed is not registerd", this.reg
|
||||
.isServiceRegistered(null));
|
||||
assertFalse("Feed is not registerd", this.reg
|
||||
.isServiceRegistered("something"));
|
||||
|
||||
}
|
||||
|
||||
private void registerService(String servicename) {
|
||||
|
||||
this.configurator.setName(servicename);
|
||||
this.reg.registerService(this.configurator);
|
||||
}
|
||||
|
||||
public void testRegisterComponent() throws RegistryException {
|
||||
try {
|
||||
this.reg.registerComponent(StorageController.class, null);
|
||||
fail("RegistryException expected");
|
||||
} catch (RegistryException e) {
|
||||
//
|
||||
//
|
||||
}
|
||||
this.reg.registerComponent(StorageCoreController.class);
|
||||
|
||||
this.reg.registerComponent(DefaultRequestHandlerFactory.class);
|
||||
RequestHandlerFactory factory = this.reg.lookup(RequestHandlerFactory.class,ComponentType.REQUESTHANDLERFACTORY);
|
||||
try{
|
||||
this.reg.registerComponent(DefaultRequestHandlerFactory.class);
|
||||
fail("RegistryException expected");
|
||||
new GDataRequestListener();
|
||||
try {
|
||||
this.reg.registerComponent(StorageCoreController.class, null);
|
||||
fail("no config");
|
||||
} catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
this.reg.registerComponent(DefaultRequestHandlerFactory.class, null);
|
||||
RequestHandlerFactory factory = this.reg.lookup(
|
||||
RequestHandlerFactory.class,
|
||||
ComponentType.REQUESTHANDLERFACTORY);
|
||||
try {
|
||||
this.reg
|
||||
.registerComponent(DefaultRequestHandlerFactory.class, null);
|
||||
fail("RegistryException expected");
|
||||
} catch (RegistryException e) {
|
||||
//
|
||||
//
|
||||
}
|
||||
this.reg.registerComponent(ServiceFactory.class);
|
||||
ServiceFactory servicefactory = this.reg.lookup(ServiceFactory.class,ComponentType.SERVICEFACTORY);
|
||||
this.reg.registerComponent(ServiceFactory.class, null);
|
||||
ServiceFactory servicefactory = this.reg.lookup(ServiceFactory.class,
|
||||
ComponentType.SERVICEFACTORY);
|
||||
assertNotNull(servicefactory);
|
||||
assertNotNull(factory);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ public class TestAbstractFeedHandler extends TestCase {
|
|||
|
||||
try {
|
||||
|
||||
GDataServerRegistry.getRegistry().registerComponent(StorageStub.class);
|
||||
GDataServerRegistry.getRegistry().registerComponent(ServiceFactoryStub.class);
|
||||
GDataServerRegistry.getRegistry().registerComponent(StorageStub.class,null);
|
||||
GDataServerRegistry.getRegistry().registerComponent(ServiceFactoryStub.class,null);
|
||||
} catch (RegistryException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -24,8 +24,10 @@ public class TestIDGenerator extends TestCase {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
this.idgen.stopIDGenerator();
|
||||
protected void tearDown() throws Exception {
|
||||
|
||||
this.idgen.stopIDGenerator();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
/**
|
||||
* 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.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.apache.lucene.gdata.server.registry.Component;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.storage.IDGenerator;
|
||||
import org.apache.lucene.gdata.storage.Storage;
|
||||
import org.apache.lucene.gdata.storage.StorageController;
|
||||
import org.apache.lucene.gdata.storage.StorageException;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter;
|
||||
import org.apache.lucene.index.IndexModifier;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
/**
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
@Component(componentType = ComponentType.STORAGECONTROLLER)
|
||||
public class StorageCoreControllerStub extends StorageCoreController {
|
||||
private final IDGenerator idGenerator;
|
||||
|
||||
|
||||
public StorageCoreControllerStub() throws IOException, StorageException {
|
||||
try{
|
||||
this.idGenerator = new IDGenerator(5);
|
||||
}catch (NoSuchAlgorithmException e) {
|
||||
throw new StorageException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#createIndexModifier()
|
||||
*/
|
||||
@Override
|
||||
protected IndexModifier createIndexModifier() throws IOException {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#forceWrite()
|
||||
*/
|
||||
@Override
|
||||
public void forceWrite() throws IOException {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#getDirectory()
|
||||
*/
|
||||
@Override
|
||||
protected Directory getDirectory() {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#getBufferSize()
|
||||
*/
|
||||
@Override
|
||||
public int getBufferSize() {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#getStorageModifier()
|
||||
*/
|
||||
@Override
|
||||
protected StorageModifier getStorageModifier() {
|
||||
|
||||
try {
|
||||
return new StorageModifierStub();
|
||||
} catch (IOException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
} catch (StorageException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#getPersistFactor()
|
||||
*/
|
||||
@Override
|
||||
public int getPersistFactor() {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#getStorageQuery()
|
||||
*/
|
||||
@Override
|
||||
protected ReferenceCounter<StorageQuery> getStorageQuery() {
|
||||
|
||||
ReferenceCounter<StorageQuery> retVal = new ReferenceCounter<StorageQuery>(new StorageQueryStub(null,null)){
|
||||
|
||||
@Override
|
||||
protected void close() {
|
||||
//
|
||||
}
|
||||
|
||||
};
|
||||
retVal.increamentReference();
|
||||
retVal.increamentReference();
|
||||
return retVal;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#registerNewStorageQuery()
|
||||
*/
|
||||
@Override
|
||||
protected void registerNewStorageQuery() throws IOException {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#releaseId()
|
||||
*/
|
||||
@Override
|
||||
public synchronized String releaseId() throws StorageException {
|
||||
|
||||
try {
|
||||
return this.idGenerator.getUID();
|
||||
} catch (InterruptedException e) {
|
||||
|
||||
throw new StorageException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#releaseNewStorageBuffer()
|
||||
*/
|
||||
@Override
|
||||
protected StorageBuffer releaseNewStorageBuffer() {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#setBufferSize(int)
|
||||
*/
|
||||
@Override
|
||||
public void setBufferSize(int storageBufferSize) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#setPersistFactor(int)
|
||||
*/
|
||||
@Override
|
||||
public void setPersistFactor(int storagePersistFactor) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#destroy()
|
||||
*/
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
this.idGenerator.stopIDGenerator();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#getStorage()
|
||||
*/
|
||||
@Override
|
||||
public Storage getStorage() throws StorageException {
|
||||
|
||||
return new StorageImplementation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#initialize()
|
||||
*/
|
||||
@Override
|
||||
public void initialize() {
|
||||
// this.setStorageDir(new RAMDirectory());
|
||||
// super.initialize();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -32,7 +32,10 @@ import org.apache.lucene.store.RAMDirectory;
|
|||
*
|
||||
*/
|
||||
public class StorageModifierStub extends StorageModifier {
|
||||
|
||||
public boolean throwException = false;
|
||||
public StorageModifierStub() throws IOException, StorageException{
|
||||
super(new StorageCoreControllerStub(), new IndexModifier(new RAMDirectory(),new StandardAnalyzer(),true), new StorageBuffer(1),1, 1);
|
||||
}
|
||||
/**
|
||||
* @param controller
|
||||
* @param modifier
|
||||
|
@ -46,7 +49,7 @@ public class StorageModifierStub extends StorageModifier {
|
|||
IndexModifier modifier, StorageBuffer buffer, int persitsFactor,
|
||||
int optimizeInterval) throws IOException, StorageException {
|
||||
|
||||
super(new StorageCoreController(), new IndexModifier(new RAMDirectory(),new StandardAnalyzer(),true), new StorageBuffer(1),1, 1);
|
||||
super(new StorageCoreControllerStub(), new IndexModifier(new RAMDirectory(),new StandardAnalyzer(),true), new StorageBuffer(1),1, 1);
|
||||
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
@ -56,7 +59,8 @@ public class StorageModifierStub extends StorageModifier {
|
|||
*/
|
||||
@Override
|
||||
protected void close() throws IOException {
|
||||
|
||||
if(throwException)
|
||||
throw new IOException();
|
||||
|
||||
}
|
||||
|
||||
|
@ -65,7 +69,8 @@ public class StorageModifierStub extends StorageModifier {
|
|||
*/
|
||||
@Override
|
||||
public void createAccount(StorageAccountWrapper account) throws StorageException {
|
||||
|
||||
if(throwException)
|
||||
throw new StorageException();
|
||||
|
||||
}
|
||||
|
||||
|
@ -74,7 +79,8 @@ public class StorageModifierStub extends StorageModifier {
|
|||
*/
|
||||
@Override
|
||||
public void createFeed(StorageFeedWrapper wrapper) throws StorageException {
|
||||
|
||||
if(throwException)
|
||||
throw new StorageException();
|
||||
|
||||
}
|
||||
|
||||
|
@ -83,7 +89,8 @@ public class StorageModifierStub extends StorageModifier {
|
|||
*/
|
||||
@Override
|
||||
public void deleteAccount(String accountName) throws StorageException {
|
||||
|
||||
if(throwException)
|
||||
throw new StorageException();
|
||||
|
||||
}
|
||||
|
||||
|
@ -92,7 +99,8 @@ public class StorageModifierStub extends StorageModifier {
|
|||
*/
|
||||
@Override
|
||||
public void deleteEntry(StorageEntryWrapper wrapper) throws StorageException {
|
||||
|
||||
if(throwException)
|
||||
throw new StorageException();
|
||||
|
||||
}
|
||||
|
||||
|
@ -101,7 +109,8 @@ public class StorageModifierStub extends StorageModifier {
|
|||
*/
|
||||
@Override
|
||||
public void deleteFeed(String feedId) throws StorageException {
|
||||
|
||||
if(throwException)
|
||||
throw new StorageException();
|
||||
|
||||
}
|
||||
|
||||
|
@ -109,8 +118,9 @@ public class StorageModifierStub extends StorageModifier {
|
|||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier#forceWrite()
|
||||
*/
|
||||
@Override
|
||||
protected void forceWrite() throws IOException {
|
||||
|
||||
public void forceWrite() throws IOException {
|
||||
if(throwException)
|
||||
throw new IOException();
|
||||
|
||||
}
|
||||
|
||||
|
@ -119,7 +129,8 @@ public class StorageModifierStub extends StorageModifier {
|
|||
*/
|
||||
@Override
|
||||
public void insertEntry(StorageEntryWrapper wrapper) throws StorageException {
|
||||
|
||||
if(throwException)
|
||||
throw new StorageException();
|
||||
|
||||
}
|
||||
|
||||
|
@ -128,7 +139,8 @@ public class StorageModifierStub extends StorageModifier {
|
|||
*/
|
||||
@Override
|
||||
public void updateAccount(StorageAccountWrapper user) throws StorageException {
|
||||
|
||||
if(throwException)
|
||||
throw new StorageException();
|
||||
|
||||
}
|
||||
|
||||
|
@ -137,8 +149,10 @@ public class StorageModifierStub extends StorageModifier {
|
|||
*/
|
||||
@Override
|
||||
public void updateEntry(StorageEntryWrapper wrapper) throws StorageException {
|
||||
|
||||
|
||||
if(throwException)
|
||||
throw new StorageException();
|
||||
if(wrapper != null)
|
||||
wrapper.getEntry();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,7 +160,8 @@ public class StorageModifierStub extends StorageModifier {
|
|||
*/
|
||||
@Override
|
||||
public void updateFeed(StorageFeedWrapper wrapper) throws StorageException {
|
||||
|
||||
if(throwException)
|
||||
throw new StorageException();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/**
|
||||
* 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.lucene.gdata.data.GDataAccount;
|
||||
import org.apache.lucene.gdata.server.registry.ProvidedService;
|
||||
import org.apache.lucene.gdata.storage.StorageException;
|
||||
import org.apache.lucene.search.Searcher;
|
||||
|
||||
import com.google.gdata.data.BaseEntry;
|
||||
import com.google.gdata.data.BaseFeed;
|
||||
import com.google.gdata.util.ParseException;
|
||||
|
||||
/**
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public class StorageQueryStub extends StorageQuery {
|
||||
|
||||
public boolean booleanReturn = true;
|
||||
|
||||
/**
|
||||
* @param buffer
|
||||
* @param searcher
|
||||
*/
|
||||
public StorageQueryStub(StorageBuffer buffer, Searcher searcher) {
|
||||
super(buffer, searcher);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#checkEntryVersion(java.lang.String, java.lang.String, int)
|
||||
*/
|
||||
@Override
|
||||
protected boolean checkEntryVersion(String id, String feedId, int version) throws IOException {
|
||||
|
||||
return booleanReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#close()
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
|
||||
super.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#entryQuery(java.util.List, java.lang.String, org.apache.lucene.gdata.server.registry.ProvidedService)
|
||||
*/
|
||||
@Override
|
||||
public List<BaseEntry> entryQuery(List<String> entryIds, String feedId, ProvidedService config) throws IOException, ParseException {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#getAccountNameForFeedId(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public String getAccountNameForFeedId(String feedId) throws IOException {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#getEntryLastModified(java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected long getEntryLastModified(String entryId, String feedId) throws IOException, StorageException {
|
||||
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#getFeedLastModified(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected long getFeedLastModified(String feedId) throws IOException {
|
||||
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#getLatestFeedQuery(java.lang.String, int, int, org.apache.lucene.gdata.server.registry.ProvidedService)
|
||||
*/
|
||||
@Override
|
||||
public BaseFeed getLatestFeedQuery(String feedId, int resultCount, int startIndex, ProvidedService config) throws IOException, ParseException {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#getService(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public String getService(String feedID) throws IOException {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#getUser(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public GDataAccount getUser(String username) throws IOException {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#isEntryStored(java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected boolean isEntryStored(String entryId, String feedId) throws IOException {
|
||||
|
||||
return booleanReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#isFeedStored(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean isFeedStored(String feedId) throws IOException {
|
||||
|
||||
return booleanReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.storage.lucenestorage.StorageQuery#singleEntryQuery(java.lang.String, java.lang.String, org.apache.lucene.gdata.server.registry.ProvidedService)
|
||||
*/
|
||||
@Override
|
||||
public BaseEntry singleEntryQuery(String entryId, String feedId, ProvidedService config) throws IOException, ParseException {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
package org.apache.lucene.gdata.storage.lucenestorage;
|
||||
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.SingleHostConcurrentStorageLock.ConcurrencyException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class TestSingelHostConcurrencyLock extends TestCase {
|
||||
SingleHostConcurrentStorageLock lock;
|
||||
boolean threadResult = false;
|
||||
protected void setUp() throws Exception {
|
||||
this.lock = (SingleHostConcurrentStorageLock)SingleHostConcurrentStorageLock.getConcurrentStorageLock();
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
threadResult = false;
|
||||
this.lock.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.SingleHostConcurrentStorageLock.getConcurrentStorageLock()'
|
||||
*/
|
||||
public void testGetConcurrentStorageLock() {
|
||||
ConcurrentStorageLock lock = SingleHostConcurrentStorageLock.getConcurrentStorageLock();
|
||||
assertEquals(lock,SingleHostConcurrentStorageLock.getConcurrentStorageLock() );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.SingleHostConcurrentStorageLock.setLock(String)'
|
||||
*/
|
||||
public void testSetLock() throws InterruptedException {
|
||||
final String key = "someKey";
|
||||
final String nextKey = "fooKey";
|
||||
assertTrue(lock.setLock(key));
|
||||
assertTrue(lock.isKeyLocked(key));
|
||||
|
||||
try{
|
||||
this.lock.setLock(key);
|
||||
fail("thread has already locked the key");
|
||||
}catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
|
||||
try{
|
||||
assertTrue(lock.setLock(nextKey));
|
||||
fail("thread has already locked the key");
|
||||
}catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
|
||||
Thread t = new Thread(new Runnable(){
|
||||
public void run(){
|
||||
threadResult = lock.setLock(key);
|
||||
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
t.join(300);
|
||||
assertFalse(threadResult);
|
||||
|
||||
t = new Thread(new Runnable(){
|
||||
public void run(){
|
||||
threadResult = lock.setLock(nextKey);
|
||||
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
t.join(300);
|
||||
assertTrue(threadResult);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.SingleHostConcurrentStorageLock.releaseLock(String)'
|
||||
*/
|
||||
public void testReleaseLock() throws InterruptedException {
|
||||
final String key = "someKey";
|
||||
final String nextKey = "fooKey";
|
||||
assertTrue(lock.setLock(key));
|
||||
assertTrue(lock.isKeyLocked(key));
|
||||
assertTrue(lock.releaseLock(key));
|
||||
assertTrue(this.lock.setLock(key));
|
||||
try{
|
||||
assertTrue(lock.setLock(nextKey));
|
||||
fail("thread has already locked the key");
|
||||
}catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
|
||||
Thread t = new Thread(new Runnable(){
|
||||
public void run(){
|
||||
threadResult = lock.setLock(nextKey);
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
t.join(300);
|
||||
assertTrue(threadResult);
|
||||
try{
|
||||
this.lock.releaseLock(nextKey);
|
||||
fail("current thread is not owner");
|
||||
}catch (ConcurrencyException e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.SingleHostConcurrentStorageLock.releaseThreadLocks()'
|
||||
*/
|
||||
public void testReleaseThreadLocks() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.SingleHostConcurrentStorageLock.isKeyLocked(String)'
|
||||
*/
|
||||
public void testIsKeyLocked() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.SingleHostConcurrentStorageLock.close()'
|
||||
*/
|
||||
public void testClose() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,236 @@
|
|||
package org.apache.lucene.gdata.storage.lucenestorage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.lucene.gdata.data.ServerBaseEntry;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
|
||||
import org.apache.lucene.gdata.utils.ProvidedServiceStub;
|
||||
|
||||
import com.google.gdata.data.DateTime;
|
||||
|
||||
public class TestStorageBuffer extends TestCase {
|
||||
private static final String FEEDID = "feed";
|
||||
private static final String ENTRYID = "someID";
|
||||
private StorageBuffer buffer;
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
this.buffer = new StorageBuffer(10);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
this.buffer.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer.StorageBuffer(int)'
|
||||
*/
|
||||
public void testStorageBuffer() {
|
||||
assertEquals(StorageBuffer.DEFAULT_BUFFER_COUNT,new StorageBuffer(StorageBuffer.DEFAULT_BUFFER_COUNT-1).getBufferSize());
|
||||
assertEquals(StorageBuffer.DEFAULT_BUFFER_COUNT,new StorageBuffer(StorageBuffer.DEFAULT_BUFFER_COUNT).getBufferSize());
|
||||
assertEquals(StorageBuffer.DEFAULT_BUFFER_COUNT+1,new StorageBuffer(StorageBuffer.DEFAULT_BUFFER_COUNT+1).getBufferSize());
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer.addEntry(StorageEntryWrapper)'
|
||||
*/
|
||||
public void testAddEntry() throws IOException {
|
||||
|
||||
ServerBaseEntry e = createServerBaseEntry(ENTRYID,FEEDID);
|
||||
StorageEntryWrapper wrapper = new StorageEntryWrapper(e,StorageOperation.INSERT);
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertEquals(1,this.buffer.getSortedEntries(FEEDID).size());
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertEquals(1,this.buffer.getSortedEntries(FEEDID).size());
|
||||
|
||||
e.setId("someotherID");
|
||||
e.setFeedId(FEEDID);
|
||||
e.setServiceConfig(new ProvidedServiceStub());
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.INSERT);
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertEquals(2,this.buffer.getSortedEntries(FEEDID).size());
|
||||
e.setId("someotherID");
|
||||
e.setFeedId("someOtherFeed");
|
||||
e.setServiceConfig(new ProvidedServiceStub());
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.UPDATE);
|
||||
this.buffer.addEntry(wrapper);
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.DELETE);
|
||||
e.setId("deleted and ingnored");
|
||||
e.setFeedId("someOtherFeed");
|
||||
e.setServiceConfig(new ProvidedServiceStub());
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertEquals(2,this.buffer.getSortedEntries(FEEDID).size());
|
||||
assertEquals(1,this.buffer.getSortedEntries("someOtherFeed").size());
|
||||
assertEquals("Contains 2 different IDs",2,this.buffer.getExculdList().length);
|
||||
|
||||
}
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer.addDeleted(String, String)'
|
||||
*/
|
||||
public void testAddDeleted() throws IOException {
|
||||
|
||||
this.buffer.addDeleted(ENTRYID,FEEDID);
|
||||
assertNull(this.buffer.getSortedEntries(FEEDID));
|
||||
assertEquals(1,this.buffer.getExculdList().length);
|
||||
assertEquals(ENTRYID,this.buffer.getExculdList()[0]);
|
||||
|
||||
this.buffer.addDeleted(ENTRYID,FEEDID);
|
||||
assertNull(this.buffer.getSortedEntries(FEEDID));
|
||||
assertEquals(1,this.buffer.getExculdList().length);
|
||||
assertEquals(ENTRYID,this.buffer.getExculdList()[0]);
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer.getFeedLastModified(String)'
|
||||
*/
|
||||
public void testGetFeedLastModified() throws IOException, InterruptedException {
|
||||
ServerBaseEntry e = createServerBaseEntry(ENTRYID,FEEDID);
|
||||
e.setUpdated(new DateTime(System.currentTimeMillis()-200,0));
|
||||
StorageEntryWrapper wrapper = new StorageEntryWrapper(e,StorageOperation.INSERT);
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertEquals(new Long(e.getUpdated().getValue()),this.buffer.getFeedLastModified(FEEDID));
|
||||
//test update
|
||||
// force timestamp
|
||||
e.setUpdated(new DateTime(System.currentTimeMillis()-180,0));
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.UPDATE);
|
||||
this.buffer.addEntry(wrapper);
|
||||
Long firstAddTimestamp = new Long(e.getUpdated().getValue());
|
||||
assertEquals(firstAddTimestamp,this.buffer.getFeedLastModified(FEEDID));
|
||||
// force timestamp
|
||||
e.setUpdated(new DateTime(System.currentTimeMillis()-160,0));
|
||||
assertFalse("updated after add" ,e.getUpdated().equals(this.buffer.getFeedLastModified(FEEDID)));
|
||||
|
||||
//insert for other feed
|
||||
String otherID = "someOtherFeedID";
|
||||
e.setFeedId(otherID);
|
||||
// force timestamp
|
||||
e.setUpdated(new DateTime(System.currentTimeMillis()-140,0));
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.INSERT);
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertEquals(new Long(e.getUpdated().getValue()),this.buffer.getFeedLastModified(otherID));
|
||||
assertEquals(firstAddTimestamp,this.buffer.getFeedLastModified(FEEDID));
|
||||
|
||||
assertTrue(firstAddTimestamp.equals(this.buffer.getFeedLastModified(FEEDID)));
|
||||
this.buffer.addDeleted(e.getId(),FEEDID);
|
||||
// time will be set inside the buffer
|
||||
assertTrue(firstAddTimestamp < this.buffer.getFeedLastModified(FEEDID));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer.getSortedEntries(String)'
|
||||
*/
|
||||
public void testGetSortedEntries() throws IOException, InterruptedException {
|
||||
assertNull(this.buffer.getSortedEntries(FEEDID));
|
||||
ServerBaseEntry e = createServerBaseEntry("2",FEEDID);
|
||||
e.setUpdated(new DateTime(System.currentTimeMillis()-200,0));
|
||||
StorageEntryWrapper wrapper = new StorageEntryWrapper(e,StorageOperation.INSERT);
|
||||
this.buffer.addEntry(wrapper);
|
||||
e.setId("0");
|
||||
// force timestamp
|
||||
e.setUpdated(new DateTime(System.currentTimeMillis()-180,0));
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.INSERT);
|
||||
this.buffer.addEntry(wrapper);
|
||||
e.setId("1");
|
||||
// force timestamp
|
||||
e.setUpdated(new DateTime(System.currentTimeMillis()-160,0));
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.INSERT);
|
||||
this.buffer.addEntry(wrapper);
|
||||
e.setId("0");
|
||||
// force timestamp
|
||||
e.setUpdated(new DateTime(System.currentTimeMillis()-140,0));
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.UPDATE);
|
||||
this.buffer.addEntry(wrapper);
|
||||
// force timestamp
|
||||
e.setUpdated(new DateTime(System.currentTimeMillis()-120,0));
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.DELETE);
|
||||
this.buffer.addEntry(wrapper);
|
||||
List<StorageEntryWrapper> list = this.buffer.getSortedEntries(FEEDID);
|
||||
assertEquals(3,list.size());
|
||||
for (int i = 0; i < 3; i++) {
|
||||
assertEquals(""+i,list.get(i).getEntryId());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer.getEntry(String, String)'
|
||||
*/
|
||||
public void testGetEntry() throws IOException {
|
||||
assertNull(this.buffer.getEntry(ENTRYID,FEEDID));
|
||||
ServerBaseEntry e = createServerBaseEntry(ENTRYID,FEEDID);
|
||||
StorageEntryWrapper wrapper = new StorageEntryWrapper(e,StorageOperation.INSERT);
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertSame(wrapper,this.buffer.getEntry(ENTRYID,FEEDID));
|
||||
|
||||
e = createServerBaseEntry("0",FEEDID);
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.UPDATE);
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertSame(wrapper,this.buffer.getEntry("0",FEEDID));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer.getExculdList()'
|
||||
*/
|
||||
public void testGetExculdList() throws IOException {
|
||||
ServerBaseEntry e = createServerBaseEntry(ENTRYID,FEEDID);
|
||||
StorageEntryWrapper wrapper = new StorageEntryWrapper(e,StorageOperation.INSERT);
|
||||
this.buffer.addEntry(wrapper);
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertEquals(1,this.buffer.getExculdList().length);
|
||||
assertEquals(wrapper.getEntryId(),this.buffer.getExculdList()[0]);
|
||||
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.UPDATE);
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertEquals(1,this.buffer.getExculdList().length);
|
||||
assertEquals(wrapper.getEntryId(),this.buffer.getExculdList()[0]);
|
||||
this.buffer.addDeleted(ENTRYID,FEEDID);
|
||||
assertEquals(1,this.buffer.getExculdList().length);
|
||||
assertEquals(wrapper.getEntryId(),this.buffer.getExculdList()[0]);
|
||||
|
||||
e = createServerBaseEntry("someOtherEntry","someOtherFeed");
|
||||
wrapper = new StorageEntryWrapper(e,StorageOperation.INSERT);
|
||||
this.buffer.addEntry(wrapper);
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertEquals(2,this.buffer.getExculdList().length);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer.close()'
|
||||
*/
|
||||
public void testClose() throws IOException {
|
||||
ServerBaseEntry e = createServerBaseEntry(ENTRYID,FEEDID);
|
||||
StorageEntryWrapper wrapper = new StorageEntryWrapper(e,StorageOperation.INSERT);
|
||||
|
||||
this.buffer.addEntry(wrapper);
|
||||
assertNotNull(this.buffer.getSortedEntries(FEEDID));
|
||||
assertNotNull(this.buffer.getEntry(ENTRYID,FEEDID));
|
||||
assertEquals(1,this.buffer.getExculdList().length);
|
||||
this.buffer.close();
|
||||
assertNull(this.buffer.getSortedEntries(FEEDID));
|
||||
assertNull(this.buffer.getEntry(ENTRYID,FEEDID));
|
||||
assertEquals(0,this.buffer.getExculdList().length);
|
||||
|
||||
|
||||
|
||||
}
|
||||
public ServerBaseEntry createServerBaseEntry(String entryID, String feedId) throws IOException{
|
||||
ServerBaseEntry e = new ServerBaseEntry();
|
||||
e.setId(entryID);
|
||||
e.setFeedId(feedId);
|
||||
e.setServiceConfig(new ProvidedServiceStub());
|
||||
return e;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,443 @@
|
|||
package org.apache.lucene.gdata.storage.lucenestorage;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.lucene.gdata.data.ServerBaseEntry;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
|
||||
import org.apache.lucene.gdata.server.registry.ProvidedService;
|
||||
import org.apache.lucene.gdata.storage.ModificationConflictException;
|
||||
import org.apache.lucene.gdata.storage.Storage;
|
||||
import org.apache.lucene.gdata.storage.StorageController;
|
||||
import org.apache.lucene.gdata.storage.StorageException;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
|
||||
import org.apache.lucene.gdata.utils.MultiThreadEntryStub;
|
||||
import org.apache.lucene.gdata.utils.ProvidedServiceStub;
|
||||
import org.apache.lucene.gdata.utils.Visitor;
|
||||
|
||||
import com.google.gdata.data.DateTime;
|
||||
|
||||
public class TestStorageImplementation extends TestCase {
|
||||
private static GDataServerRegistry reg = null;
|
||||
|
||||
private Storage storage;
|
||||
|
||||
public static boolean fail = false;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
if (reg == null) {
|
||||
reg = GDataServerRegistry.getRegistry();
|
||||
if(reg.lookup(StorageController.class,ComponentType.STORAGECONTROLLER)!= null);
|
||||
reg.destroy();
|
||||
reg.registerComponent(StorageCoreControllerStub.class,null);
|
||||
|
||||
}
|
||||
this.storage = reg.lookup(StorageController.class,
|
||||
ComponentType.STORAGECONTROLLER).getStorage();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
this.storage.close();
|
||||
fail = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.storeEntry(ServerBaseEntry)'
|
||||
*/
|
||||
public void testStoreEntry() {
|
||||
|
||||
try {
|
||||
this.storage.storeEntry(null);
|
||||
fail("entry is null");
|
||||
} catch (StorageException e) {
|
||||
//
|
||||
}
|
||||
ServerBaseEntry entry = new ServerBaseEntry();
|
||||
entry.setServiceConfig(new ProvidedServiceStub());
|
||||
|
||||
try {
|
||||
this.storage.storeEntry(entry);
|
||||
fail("feed is null");
|
||||
} catch (StorageException e) {
|
||||
//
|
||||
}
|
||||
|
||||
entry.setFeedId("someID");
|
||||
try {
|
||||
this.storage.storeEntry(entry);
|
||||
|
||||
} catch (StorageException e1) {
|
||||
fail("unexpected exception");
|
||||
|
||||
}
|
||||
entry.setServiceConfig(null);
|
||||
try {
|
||||
this.storage.storeEntry(entry);
|
||||
fail("no service config");
|
||||
} catch (StorageException e) {
|
||||
|
||||
}
|
||||
entry.setVersion(5);
|
||||
try {
|
||||
this.storage.storeEntry(entry);
|
||||
fail("version is greater than 1");
|
||||
} catch (StorageException e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.deleteEntry(ServerBaseEntry)'
|
||||
*/
|
||||
public void testDeleteEntry() throws InterruptedException {
|
||||
try {
|
||||
this.storage.storeEntry(null);
|
||||
fail("entry is null");
|
||||
} catch (StorageException e) {
|
||||
//
|
||||
}
|
||||
ServerBaseEntry entry = new ServerBaseEntry();
|
||||
entry.setServiceConfig(new ProvidedServiceStub());
|
||||
entry.setId("someID");
|
||||
entry.setFeedId("someID");
|
||||
try {
|
||||
this.storage.storeEntry(entry);
|
||||
|
||||
} catch (StorageException e) {
|
||||
fail("unexpected exception");
|
||||
//
|
||||
}
|
||||
entry.setFeedId(null);
|
||||
try {
|
||||
this.storage.deleteEntry(entry);
|
||||
fail("feed is null");
|
||||
} catch (StorageException e) {
|
||||
//
|
||||
}
|
||||
|
||||
entry.setFeedId("someID");
|
||||
try {
|
||||
this.storage.deleteEntry(entry);
|
||||
|
||||
} catch (StorageException e1) {
|
||||
e1.printStackTrace();
|
||||
fail("unexpected exception");
|
||||
|
||||
}
|
||||
entry.setFeedId("someID");
|
||||
|
||||
try {
|
||||
this.storage.deleteEntry(entry);
|
||||
|
||||
} catch (StorageException e1) {
|
||||
e1.printStackTrace();
|
||||
fail("unexpected exception");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Object monitor = new Object();
|
||||
AtomicBoolean reached = new AtomicBoolean(false);
|
||||
|
||||
MultiThreadEntryStub concuEntry = new MultiThreadEntryStub();
|
||||
concuEntry.setId(System.currentTimeMillis() + "");
|
||||
ProvidedService conf = new ProvidedServiceStub();
|
||||
|
||||
concuEntry.setServiceConfig(conf);
|
||||
concuEntry.setUpdated(DateTime.now());
|
||||
concuEntry.setFeedId("feed");
|
||||
this.storage.storeEntry(concuEntry);
|
||||
storage.close();
|
||||
concuEntry.acceptGetVersionVisitor(getMonitorVisitor(monitor,reached));
|
||||
|
||||
|
||||
Thread t1 = getDelThread(storage, concuEntry, false);
|
||||
|
||||
Thread t2 = getDelThread(storage, concuEntry, true);
|
||||
t1.start();
|
||||
/*
|
||||
* Wait active -- not nice but works fine here
|
||||
* wait until thread parked
|
||||
*/
|
||||
|
||||
while (true) {
|
||||
synchronized (monitor) {
|
||||
if (reached.get())
|
||||
break;
|
||||
monitor.wait(10);
|
||||
}
|
||||
}
|
||||
t2.start();
|
||||
t2.join(800);
|
||||
/*
|
||||
* Wait active -- not nice but works fine here
|
||||
* wake up the waiting thread
|
||||
*/
|
||||
while (true) {
|
||||
synchronized (monitor) {
|
||||
if (!reached.get())
|
||||
break;
|
||||
monitor.notifyAll();
|
||||
}
|
||||
}
|
||||
t1.join(300);
|
||||
if (fail)
|
||||
fail("thread failed -- see stacktrace");
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.updateEntry(ServerBaseEntry)'
|
||||
*/
|
||||
public void testUpdateEntry() throws InterruptedException {
|
||||
Object monitor = new Object();
|
||||
AtomicBoolean reached = new AtomicBoolean(false);
|
||||
|
||||
MultiThreadEntryStub concuEntry = new MultiThreadEntryStub();
|
||||
concuEntry.setId(System.currentTimeMillis() + "");
|
||||
ProvidedService conf = new ProvidedServiceStub();
|
||||
|
||||
concuEntry.setServiceConfig(conf);
|
||||
concuEntry.setUpdated(DateTime.now());
|
||||
concuEntry.setFeedId("feed");
|
||||
this.storage.storeEntry(concuEntry);
|
||||
storage.close();
|
||||
concuEntry.acceptGetEntryVisitor(getMonitorVisitor(monitor,reached));
|
||||
|
||||
|
||||
Thread t1 = getUpdThread(storage, concuEntry, false);
|
||||
|
||||
Thread t2 = getUpdThread(storage, concuEntry, true);
|
||||
t1.start();
|
||||
/*
|
||||
* Wait active -- not nice but works fine here
|
||||
* wait until thread parked
|
||||
*/
|
||||
|
||||
while (true) {
|
||||
synchronized (monitor) {
|
||||
if (reached.get())
|
||||
break;
|
||||
monitor.wait(10);
|
||||
}
|
||||
}
|
||||
t2.start();
|
||||
t2.join(800);
|
||||
/*
|
||||
* Wait active -- not nice but works fine here
|
||||
* wake up the waiting thread
|
||||
*/
|
||||
while (true) {
|
||||
synchronized (monitor) {
|
||||
if (!reached.get())
|
||||
break;
|
||||
monitor.notifyAll();
|
||||
}
|
||||
}
|
||||
t1.join(300);
|
||||
if (fail)
|
||||
fail("thread failed -- see stacktrace");
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.getFeed(ServerBaseFeed)'
|
||||
*/
|
||||
public void testGetFeed() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.getEntry(ServerBaseEntry)'
|
||||
*/
|
||||
public void testGetEntry() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.close()'
|
||||
*/
|
||||
public void testClose() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.storeAccount(GDataAccount)'
|
||||
*/
|
||||
public void testStoreAccount() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.updateAccount(GDataAccount)'
|
||||
*/
|
||||
public void testUpdateAccount() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.deleteAccount(String)'
|
||||
*/
|
||||
public void testDeleteAccount() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.storeFeed(ServerBaseFeed,
|
||||
* String)'
|
||||
*/
|
||||
public void testStoreFeed() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.deleteFeed(String)'
|
||||
*/
|
||||
public void testDeleteFeed() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.updateFeed(ServerBaseFeed,
|
||||
* String)'
|
||||
*/
|
||||
public void testUpdateFeed() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.getServiceForFeed(String)'
|
||||
*/
|
||||
public void testGetServiceForFeed() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.getAccount(String)'
|
||||
*/
|
||||
public void testGetAccount() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.getAccountNameForFeedId(String)'
|
||||
*/
|
||||
public void testGetAccountNameForFeedId() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.getEntryLastModified(String,
|
||||
* String)'
|
||||
*/
|
||||
public void testGetEntryLastModified() {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for
|
||||
* 'org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation.getFeedLastModified(String)'
|
||||
*/
|
||||
public void testGetFeedLastModified() {
|
||||
|
||||
}
|
||||
static class Runner implements Runnable {
|
||||
Storage s;
|
||||
|
||||
StorageController c;
|
||||
|
||||
ServerBaseEntry e;
|
||||
|
||||
boolean expConf;
|
||||
|
||||
StorageOperation op;
|
||||
|
||||
public Runner(Storage s, ServerBaseEntry e,
|
||||
boolean expectConflict, StorageOperation op) {
|
||||
this.s = s;
|
||||
this.e = e;
|
||||
this.expConf = expectConflict;
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
if (this.op == StorageOperation.DELETE)
|
||||
this.s.deleteEntry(e);
|
||||
if (this.op == StorageOperation.UPDATE)
|
||||
this.s.updateEntry(e);
|
||||
if (expConf)
|
||||
fail = true;
|
||||
} catch (ModificationConflictException ex) {
|
||||
if (!expConf)
|
||||
fail = true;
|
||||
ex.printStackTrace();
|
||||
|
||||
} catch (StorageException ex) {
|
||||
ex.printStackTrace();
|
||||
fail = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private Visitor getMonitorVisitor(final Object monitor, final AtomicBoolean reached){
|
||||
/*
|
||||
* The executing thread stops at a defined position while holding the semaphore inside the storageImpl
|
||||
*/
|
||||
return new Visitor(){
|
||||
public void execute(Object[] o){
|
||||
synchronized (monitor) {
|
||||
try {
|
||||
reached.set(true);
|
||||
monitor.wait();
|
||||
reached.set(false);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Thread getDelThread(Storage s, ServerBaseEntry e,
|
||||
boolean conflictExpected) {
|
||||
Thread t1 = new Thread(new Runner(s, e, conflictExpected,
|
||||
StorageOperation.DELETE));
|
||||
t1.setPriority(Thread.MAX_PRIORITY);
|
||||
return t1;
|
||||
}
|
||||
|
||||
private Thread getUpdThread(Storage s, ServerBaseEntry e,
|
||||
boolean conflictExpected) {
|
||||
Thread t1 = new Thread(new Runner(s, e, conflictExpected,
|
||||
StorageOperation.UPDATE));
|
||||
t1.setPriority(Thread.MAX_PRIORITY);
|
||||
return t1;
|
||||
}
|
||||
|
||||
}
|
|
@ -7,10 +7,7 @@ import junit.framework.TestCase;
|
|||
import org.apache.lucene.gdata.data.GDataAccount;
|
||||
import org.apache.lucene.gdata.data.ServerBaseEntry;
|
||||
import org.apache.lucene.gdata.data.ServerBaseFeed;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
|
||||
import org.apache.lucene.gdata.server.registry.ProvidedService;
|
||||
import org.apache.lucene.gdata.storage.StorageController;
|
||||
import org.apache.lucene.gdata.storage.StorageException;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter;
|
||||
|
@ -23,6 +20,7 @@ import org.apache.lucene.search.IndexSearcher;
|
|||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
import com.google.gdata.data.BaseEntry;
|
||||
import com.google.gdata.data.DateTime;
|
||||
|
@ -50,13 +48,16 @@ public class TestStorageModifier extends TestCase {
|
|||
private static String service = "myService";
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
GDataServerRegistry.getRegistry().registerComponent(
|
||||
StorageCoreController.class);
|
||||
this.controller = new StorageCoreController();
|
||||
this.dir = new RAMDirectory();
|
||||
this.controller.setStorageDir(this.dir);
|
||||
this.controller.setKeepRecoveredFiles(false);
|
||||
this.controller.setOptimizeInterval(10);
|
||||
this.controller.setRecover(false);
|
||||
this.controller.setBufferSize(10);
|
||||
this.controller.setPersistFactor(10);
|
||||
this.controller.initialize();
|
||||
this.configurator = new ProvidedServiceStub();
|
||||
GDataServerRegistry.getRegistry().registerService(this.configurator);
|
||||
this.controller = (StorageCoreController) GDataServerRegistry
|
||||
.getRegistry().lookup(StorageController.class,
|
||||
ComponentType.STORAGECONTROLLER);
|
||||
this.modifier = this.controller.getStorageModifier();
|
||||
this.dir = this.controller.getDirectory();
|
||||
|
||||
|
@ -65,8 +66,9 @@ public class TestStorageModifier extends TestCase {
|
|||
protected void tearDown() throws Exception {
|
||||
this.count = 1;
|
||||
// destroy all resources
|
||||
GDataServerRegistry.getRegistry().destroy();// TODO remove dependency
|
||||
// here
|
||||
this.controller.destroy();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -121,7 +123,8 @@ public class TestStorageModifier extends TestCase {
|
|||
assertEquals("updated Title:", insertString, fetchedEntry
|
||||
.getTitle().getPlainText());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -132,14 +135,16 @@ public class TestStorageModifier extends TestCase {
|
|||
ParseException, StorageException {
|
||||
|
||||
Thread a = getRunnerThread(this.count);
|
||||
a.start();
|
||||
|
||||
|
||||
Thread b = getRunnerThread((this.count += 10));
|
||||
b.start();
|
||||
// wait for the first thread to check for the inserted entries
|
||||
a.start();
|
||||
// wait for the first thread to check for the inserted entries
|
||||
a.join();
|
||||
try{
|
||||
for (int i = 1; i < this.count; i++) {
|
||||
|
||||
ReferenceCounter<StorageQuery> innerQuery = this.controller
|
||||
.getStorageQuery();
|
||||
BaseEntry e = innerQuery.get().singleEntryQuery("" + i, feedId,
|
||||
|
@ -358,6 +363,7 @@ public class TestStorageModifier extends TestCase {
|
|||
StorageEntryWrapper wrapper = new StorageEntryWrapper(en,
|
||||
StorageOperation.INSERT);
|
||||
modifier.insertEntry(wrapper);
|
||||
// System.out.println("insert: "+i+" Thread: "+Thread.currentThread().getName());
|
||||
} catch (Exception e1) {
|
||||
|
||||
e1.printStackTrace();
|
||||
|
|
|
@ -10,15 +10,13 @@ import junit.framework.TestCase;
|
|||
import org.apache.lucene.gdata.data.GDataAccount;
|
||||
import org.apache.lucene.gdata.data.ServerBaseEntry;
|
||||
import org.apache.lucene.gdata.data.ServerBaseFeed;
|
||||
import org.apache.lucene.gdata.server.registry.ComponentType;
|
||||
import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
|
||||
import org.apache.lucene.gdata.server.registry.ProvidedService;
|
||||
import org.apache.lucene.gdata.storage.StorageController;
|
||||
import org.apache.lucene.gdata.storage.StorageException;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter;
|
||||
import org.apache.lucene.gdata.utils.ProvidedServiceStub;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
import com.google.gdata.data.BaseEntry;
|
||||
import com.google.gdata.data.BaseFeed;
|
||||
|
@ -37,12 +35,17 @@ public class TestStorageQuery extends TestCase {
|
|||
private static String accountName = "simon";
|
||||
private static String service = ProvidedServiceStub.SERVICE_NAME;
|
||||
protected void setUp() throws Exception {
|
||||
GDataServerRegistry.getRegistry().registerComponent(StorageCoreController.class);
|
||||
this.configurator = new ProvidedServiceStub();
|
||||
|
||||
|
||||
GDataServerRegistry.getRegistry().registerService(this.configurator);
|
||||
this.controller = (StorageCoreController)GDataServerRegistry.getRegistry().lookup(StorageController.class,ComponentType.STORAGECONTROLLER);
|
||||
this.controller = new StorageCoreController();
|
||||
this.dir = new RAMDirectory();
|
||||
this.controller.setStorageDir(this.dir);
|
||||
this.controller.setKeepRecoveredFiles(false);
|
||||
this.controller.setOptimizeInterval(10);
|
||||
this.controller.setRecover(false);
|
||||
this.controller.setBufferSize(10);
|
||||
this.controller.setPersistFactor(10);
|
||||
this.controller.initialize();
|
||||
this.configurator = new ProvidedServiceStub();
|
||||
this.modifier = this.controller.getStorageModifier();
|
||||
this.dir = this.controller.getDirectory();
|
||||
ServerBaseFeed feed = new ServerBaseFeed();
|
||||
|
@ -55,12 +58,8 @@ public class TestStorageQuery extends TestCase {
|
|||
insertEntries(this.count);
|
||||
this.query = this.controller.getStorageQuery();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param entrycount
|
||||
* @throws IOException
|
||||
|
@ -93,7 +92,7 @@ public class TestStorageQuery extends TestCase {
|
|||
|
||||
protected void tearDown() throws Exception {
|
||||
this.query.decrementRef();
|
||||
GDataServerRegistry.getRegistry().destroy();
|
||||
this.controller.destroy();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -244,6 +243,43 @@ public class TestStorageQuery extends TestCase {
|
|||
assertEquals(entry.getUpdated().getValue(),this.query.get().getFeedLastModified(feedId));
|
||||
this.query = this.controller.getStorageQuery();
|
||||
assertEquals(entry.getUpdated().getValue(),this.query.get().getFeedLastModified(feedId));
|
||||
}
|
||||
|
||||
public void testCheckVersionId() throws IOException, StorageException{
|
||||
this.modifier.forceWrite();
|
||||
ReferenceCounter<StorageQuery> sQuery = this.controller.getStorageQuery();
|
||||
ServerBaseEntry entry = new ServerBaseEntry(new Entry());
|
||||
entry.setId("test");
|
||||
entry.setServiceConfig(this.configurator);
|
||||
entry.setUpdated(new DateTime(System.currentTimeMillis(),0));
|
||||
entry.setFeedId(feedId);
|
||||
entry.setVersion(5);
|
||||
StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,StorageOperation.INSERT);
|
||||
this.modifier.insertEntry(wrapper);
|
||||
//test in buffer
|
||||
assertTrue(sQuery.get().checkEntryVersion(entry.getId(),entry.getFeedId(),entry.getVersion()));
|
||||
assertFalse(sQuery.get().checkEntryVersion(entry.getId(),entry.getFeedId(),10000));
|
||||
assertFalse(sQuery.get().checkEntryVersion(entry.getId(),"someOtherFeed",entry.getVersion()));
|
||||
assertFalse(sQuery.get().checkEntryVersion("foobar",entry.getFeedId(),entry.getVersion()));
|
||||
|
||||
|
||||
this.modifier.forceWrite();
|
||||
//test in buffer after written
|
||||
assertTrue(sQuery.get().checkEntryVersion(entry.getId(),entry.getFeedId(),entry.getVersion()));
|
||||
assertFalse(sQuery.get().checkEntryVersion(entry.getId(),entry.getFeedId(),10000));
|
||||
assertFalse(sQuery.get().checkEntryVersion(entry.getId(),"someOtherFeed",entry.getVersion()));
|
||||
assertFalse(sQuery.get().checkEntryVersion("foobar",entry.getFeedId(),entry.getVersion()));
|
||||
sQuery.decrementRef();
|
||||
sQuery = this.controller.getStorageQuery();
|
||||
//test in index
|
||||
assertTrue(sQuery.get().checkEntryVersion(entry.getId(),entry.getFeedId(),entry.getVersion()));
|
||||
assertFalse(sQuery.get().checkEntryVersion(entry.getId(),entry.getFeedId(),10000));
|
||||
assertFalse(sQuery.get().checkEntryVersion("foobar",entry.getFeedId(),entry.getVersion()));
|
||||
sQuery.decrementRef();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
private void entryQueryHelper(ReferenceCounter<StorageQuery> currentQuery) throws IOException, ParseException{
|
||||
|
||||
|
@ -255,7 +291,9 @@ public class TestStorageQuery extends TestCase {
|
|||
assertEquals(entryIdList.size(),entryList.size());
|
||||
List<String> entryIdCompare = new ArrayList<String>();
|
||||
for (BaseEntry entry : entryList) {
|
||||
assertEquals("1",entry.getVersionId());
|
||||
entryIdCompare.add(entry.getId());
|
||||
|
||||
}
|
||||
assertTrue(entryIdList.containsAll(entryIdCompare));
|
||||
|
||||
|
|
|
@ -3,35 +3,34 @@ package org.apache.lucene.gdata.storage.lucenestorage.recover;
|
|||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.rmi.registry.Registry;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.lucene.gdata.data.ServerBaseEntry;
|
||||
import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
|
||||
import org.apache.lucene.gdata.storage.StorageException;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.StorageModifier;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.StorageModifierStub;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
|
||||
import org.apache.lucene.gdata.utils.ProvidedServiceStub;
|
||||
import org.easymock.MockControl;
|
||||
|
||||
import com.google.gdata.data.DateTime;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class TestRecoverController extends TestCase {
|
||||
private RecoverController writeController;
|
||||
private RecoverController readController;
|
||||
private File recDir = new File("./temp/");
|
||||
private File recDir;
|
||||
private String feedId = "feedid";
|
||||
private String entryId = "entryId";
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
this.recDir = new File("unittest"+System.currentTimeMillis());
|
||||
if(!this.recDir.exists())
|
||||
this.recDir.mkdir();
|
||||
this.recDir.deleteOnExit();
|
||||
GDataServerRegistry.getRegistry().registerService(new ProvidedServiceStub());
|
||||
this.writeController = new RecoverController(this.recDir,false,false);
|
||||
this.readController = new RecoverController(this.recDir,true,false);
|
||||
this.writeController = new RecoverController(this.recDir,false,true);
|
||||
this.readController = new RecoverController(this.recDir,true,true);
|
||||
|
||||
|
||||
|
||||
|
@ -82,8 +81,8 @@ public class TestRecoverController extends TestCase {
|
|||
fail("unexpected exception"+e.getMessage());
|
||||
}
|
||||
this.readController.destroy();
|
||||
assertEquals(0,this.recDir.listFiles().length);
|
||||
assertNotSame(length,this.recDir.listFiles().length);
|
||||
assertEquals(1,this.recDir.listFiles().length);
|
||||
|
||||
createCorruptedFile();
|
||||
this.readController.initialize();
|
||||
try{
|
||||
|
@ -92,7 +91,7 @@ public class TestRecoverController extends TestCase {
|
|||
fail("unexpected exception"+e.getMessage());
|
||||
}
|
||||
this.readController.destroy();
|
||||
assertEquals(1,this.recDir.listFiles().length);
|
||||
assertEquals(2,this.recDir.listFiles().length);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.util.List;
|
|||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
|
||||
import org.apache.lucene.gdata.server.registry.ProvidedService;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
|
||||
import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
|
||||
import org.apache.lucene.gdata.utils.ProvidedServiceStub;
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* 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.utils;
|
||||
|
||||
|
||||
|
||||
|
||||
import org.apache.lucene.gdata.data.ServerBaseEntry;
|
||||
|
||||
import com.google.gdata.data.BaseEntry;
|
||||
|
||||
/**
|
||||
* @author Simon Willnauer
|
||||
*
|
||||
*/
|
||||
public class MultiThreadEntryStub extends ServerBaseEntry {
|
||||
|
||||
|
||||
private Visitor getEntryVisitor;
|
||||
private Visitor getVersionVisitor;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public MultiThreadEntryStub() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param arg0
|
||||
*/
|
||||
public MultiThreadEntryStub(BaseEntry arg0) {
|
||||
super(arg0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void acceptGetEntryVisitor(Visitor visitor){
|
||||
this.getEntryVisitor = visitor;
|
||||
}
|
||||
public void acceptGetVersionVisitor(Visitor visitor){
|
||||
this.getVersionVisitor = visitor;
|
||||
}
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.data.ServerBaseEntry#getEntry()
|
||||
*/
|
||||
@Override
|
||||
public BaseEntry getEntry() {
|
||||
|
||||
if(this.getEntryVisitor != null){
|
||||
this.getEntryVisitor.execute(null);
|
||||
|
||||
}
|
||||
return super.getEntry();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.apache.lucene.gdata.data.ServerBaseEntry#getVersion()
|
||||
*/
|
||||
@Override
|
||||
public int getVersion() {
|
||||
|
||||
if(this.getVersionVisitor != null){
|
||||
this.getVersionVisitor.execute(null);
|
||||
|
||||
}
|
||||
return super.getVersion();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -35,4 +35,7 @@ public class ProvidedServiceStub implements ProvidedService {
|
|||
return SERVICE_NAME;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,4 +57,9 @@ public class StorageControllerStub implements StorageController {
|
|||
public void initialize() {
|
||||
}
|
||||
|
||||
public String releaseId() {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -170,4 +170,9 @@ public static String SERVICE_TYPE_RETURN = "service";
|
|||
return null;
|
||||
}
|
||||
|
||||
public String releaseId() {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
package org.apache.lucene.gdata.utils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import com.sun.org.apache.xalan.internal.xsltc.compiler.Pattern;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
@ -18,24 +15,30 @@ public class TestDateFormater extends TestCase {
|
|||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.utils.DateFormater.formatDate(Date, String)'
|
||||
*/
|
||||
public void testFormatDate() throws ParseException {
|
||||
|
||||
// this reg. --> bit weak but does the job
|
||||
java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("[A-Z][a-z]{1,2}, [0-9]{1,2} [A-Z][a-z]{2} [0-9]{4} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2} [A-Z]{2,4}");
|
||||
Date date = new Date();
|
||||
|
||||
String formatedDate = DateFormater.formatDate(date,DateFormater.HTTP_HEADER_DATE_FORMAT);
|
||||
|
||||
assertTrue(pattern.matcher(formatedDate).matches());
|
||||
|
||||
DateFormater.parseDate("Sun, 25 Jun 2006 13:51:23 +0000",DateFormater.HTTP_HEADER_DATE_FORMAT,DateFormater.HTTP_HEADER_DATE_FORMAT_TIME_OFFSET);
|
||||
DateFormater.parseDate("Sun, 25 Jun 2006 13:51:23 CEST",DateFormater.HTTP_HEADER_DATE_FORMAT,DateFormater.HTTP_HEADER_DATE_FORMAT_TIME_OFFSET);
|
||||
//TODO extend this
|
||||
|
||||
}
|
||||
|
||||
public void testFormatDateStack(){
|
||||
DateFormater formater = new DateFormater();
|
||||
SimpleDateFormat f1 = formater.getFormater();
|
||||
SimpleDateFormat f2 = formater.getFormater();
|
||||
assertNotSame(f1,f2);
|
||||
formater.returnFomater(f1);
|
||||
assertSame(f1,formater.getFormater());
|
||||
formater.returnFomater(f2);
|
||||
assertSame(f2,formater.getFormater());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
package org.apache.lucene.gdata.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class TestSimpleObjectPool extends TestCase {
|
||||
private Pool testPool;
|
||||
private int SIZE = 10;
|
||||
protected void setUp() throws Exception {
|
||||
this.testPool =new SimpleObjectPool(SIZE,new ObjectFactoryStub());
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.utils.SimpleObjectPool.SimpleObjectPool(int, PoolObjectFactory<Type>)'
|
||||
*/
|
||||
public void testSimpleObjectPool() {
|
||||
SimpleObjectPool pool = new SimpleObjectPool(1,new ObjectFactoryStub());
|
||||
assertEquals(pool.getSize(),SimpleObjectPool.MINIMALSIZE);
|
||||
pool = new SimpleObjectPool(-100,new ObjectFactoryStub());
|
||||
assertEquals(pool.getSize(),SimpleObjectPool.MINIMALSIZE);
|
||||
pool = new SimpleObjectPool(new ObjectFactoryStub());
|
||||
assertEquals(pool.getSize(),SimpleObjectPool.DEFAULTSIZE);
|
||||
pool = new SimpleObjectPool(100,new ObjectFactoryStub());
|
||||
|
||||
assertEquals(100,pool.getSize());
|
||||
try{
|
||||
pool = new SimpleObjectPool(1,null);
|
||||
fail("factory must not be null");
|
||||
}catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.utils.SimpleObjectPool.aquire()'
|
||||
*/
|
||||
public void testAquire() {
|
||||
List l = new ArrayList(SIZE);
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Object o = this.testPool.aquire();
|
||||
assertNotNull(o);
|
||||
assertFalse(l.contains(o));
|
||||
l.add(o);
|
||||
|
||||
}
|
||||
for (Object object : l) {
|
||||
this.testPool.release(object);
|
||||
}
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Object o = this.testPool.aquire();
|
||||
assertNotNull(o);
|
||||
assertTrue(l.contains(o));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Test method for 'org.apache.lucene.gdata.utils.SimpleObjectPool.release(Type)'
|
||||
*/
|
||||
public void testRelease() {
|
||||
List l = new ArrayList(SIZE);
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Object o = this.testPool.aquire();
|
||||
assertNotNull(o);
|
||||
assertFalse(l.contains(o));
|
||||
l.add(o);
|
||||
|
||||
}
|
||||
|
||||
for (Object object : l) {
|
||||
this.testPool.release(object);
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
this.testPool.release(new Object());
|
||||
}
|
||||
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
Object o = this.testPool.aquire();
|
||||
assertNotNull(o);
|
||||
assertTrue(l.contains(o));
|
||||
|
||||
|
||||
}
|
||||
|
||||
//############################
|
||||
|
||||
for (Object object : l) {
|
||||
this.testPool.release(object);
|
||||
}
|
||||
|
||||
for (int i = 0; i < SIZE +SIZE; i++) {
|
||||
Object o = this.testPool.aquire();
|
||||
assertNotNull(o);
|
||||
|
||||
if(i>= SIZE)
|
||||
assertFalse(l.contains(o));
|
||||
else
|
||||
assertTrue(l.contains(o));
|
||||
}
|
||||
}
|
||||
|
||||
public void testDestroy(){
|
||||
this.testPool.destroy();
|
||||
try{
|
||||
this.testPool.aquire();
|
||||
fail("pool is already closed");
|
||||
}catch (Exception e) {
|
||||
// TODO: handle exception
|
||||
}
|
||||
this.testPool.release(new Object());
|
||||
}
|
||||
|
||||
static class ObjectFactoryStub implements PoolObjectFactory{
|
||||
|
||||
public Object getInstance() {
|
||||
|
||||
return new Object();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void destroyInstance(Object type) {
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package org.apache.lucene.gdata.utils;
|
||||
|
||||
public interface Visitor {
|
||||
public void execute(Object[] objects);
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gdata>
|
||||
<service name="feed" public="true">
|
||||
<service name="feed" poolSize="20" public="true">
|
||||
<feed-class>com.google.gdata.data.Feed</feed-class>
|
||||
<entry-class>com.google.gdata.data.Entry</entry-class>
|
||||
<extension-profile>
|
||||
com.google.gdata.data.ExtensionProfile
|
||||
</extension-profile>
|
||||
</service>
|
||||
<service name="calendar" public="true">
|
||||
<service name="calendar" poolSize="20" public="true">
|
||||
<feed-class>
|
||||
com.google.gdata.data.extensions.EventFeed
|
||||
</feed-class>
|
||||
|
@ -20,16 +20,34 @@
|
|||
</service>
|
||||
<server-components>
|
||||
<component>
|
||||
org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController
|
||||
<class>
|
||||
org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController
|
||||
</class>
|
||||
<configuration>
|
||||
<property name="bufferSize">20</property>
|
||||
<property name="optimizeInterval">20</property>
|
||||
<property name="persistFactor">20</property>
|
||||
<property name="directory">/tmp/storage</property>
|
||||
<property name="recover">true</property>
|
||||
<property name="keepRecoveredFiles">false</property>
|
||||
</configuration>
|
||||
</component>
|
||||
<component>
|
||||
org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory
|
||||
<class>
|
||||
org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory
|
||||
</class>
|
||||
</component>
|
||||
<component>
|
||||
org.apache.lucene.gdata.server.ServiceFactory
|
||||
<class>org.apache.lucene.gdata.server.ServiceFactory</class>
|
||||
</component>
|
||||
<component>
|
||||
org.apache.lucene.gdata.server.authentication.BlowfishAuthenticationController
|
||||
<class>
|
||||
org.apache.lucene.gdata.server.authentication.BlowfishAuthenticationController
|
||||
</class>
|
||||
<configuration>
|
||||
<property name="key">cryptKey</property>
|
||||
<property name="loginTimeout">60</property>
|
||||
</configuration>
|
||||
</component>
|
||||
</server-components>
|
||||
</gdata>
|
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<xs:element name="feed-class" type="xs:string" />
|
||||
<xs:element name="entry-class" type="xs:string" />
|
||||
<xs:element name="extension-profile" type="xs:string" />
|
||||
<xs:element name="class" type="xs:string" />
|
||||
|
||||
<xs:element name="property">
|
||||
<xs:complexType mixed="true">
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="configuration">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="property" minOccurs="1"
|
||||
maxOccurs="unbounded" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="service">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="feed-class" maxOccurs="1"
|
||||
minOccurs="1" />
|
||||
<xs:element ref="entry-class" maxOccurs="1"
|
||||
minOccurs="1" />
|
||||
<xs:element ref="extension-profile" maxOccurs="1"
|
||||
minOccurs="1" />
|
||||
</xs:sequence>
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
<xs:attribute name="public" type="xs:boolean" />
|
||||
<xs:attribute name="poolSize" type="xs:nonNegativeInteger"
|
||||
use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="component">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="class" maxOccurs="1" minOccurs="1" />
|
||||
<xs:element ref="configuration" minOccurs="0"
|
||||
maxOccurs="1" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="server-components">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="component" minOccurs="1"
|
||||
maxOccurs="unbounded" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="gdata">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="service" minOccurs="1"
|
||||
maxOccurs="unbounded" />
|
||||
<xs:element ref="server-components" maxOccurs="1"
|
||||
minOccurs="1" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
|
||||
<properties>
|
||||
<comment>Lucene Storage Properties</comment>
|
||||
<entry key="gdata.server.storage.lucene.buffersize">20</entry>
|
||||
<entry key="gdata.server.storage.lucene.persistFactor">20</entry>
|
||||
<entry key="gdata.server.storage.lucene.optimizeInterval">20</entry>
|
||||
<entry key="gdata.server.storage.lucene.directory">/tmp/storage/</entry>
|
||||
<entry key="gdata.server.storage.lucene.recover">true</entry>
|
||||
<entry key="gdata.server.storage.lucene.recover.keepFiles">false</entry>
|
||||
</properties>
|
|
@ -13,6 +13,11 @@
|
|||
org.apache.lucene.gdata.server.registry.RegistryContextListener
|
||||
</listener-class>
|
||||
</listener>
|
||||
<listener>
|
||||
<listener-class>
|
||||
org.apache.lucene.gdata.server.registry.GDataRequestListener
|
||||
</listener-class>
|
||||
</listener>
|
||||
<servlet>
|
||||
<servlet-name>ControllerServlet</servlet-name>
|
||||
<servlet-class>
|
||||
|
|
Loading…
Reference in New Issue