gdata update

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@425563 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2006-07-26 00:20:00 +00:00
parent 5e61ac9bf1
commit 729ae8f039
11 changed files with 2863 additions and 0 deletions

View File

@ -0,0 +1,79 @@
/**
* 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.configuration;
import java.util.HashMap;
import java.util.Map;
/**
* Simple configuration class storing properties as key with defined property
* values as values in a <code>Map<String,String></code>. As amap cannot
* contain duplicate keys the first use of a key can not be replaced. If a key
* is used twice a {@link java.lang.IllegalArgumentException} will be thrown.
* @see Map
* @author Simon Willnauer
*
*/
public class ComponentConfiguration {
private final Map<String, String> configMap;
/**
* Creates a new ComponentConfiguration object and initializes the internal
* map.
*/
public ComponentConfiguration() {
super();
this.configMap = new HashMap<String, String>();
}
/**
* Stores a key / value pair as a property. If a key is used twice the first
* call will set the key / value pair. Any subsequent calls with a already
* set key will throw a IllegalArgumentException.
*
* @param key -
* the property as a key
* @param value -
* the value for the key
*@see Map#put(Object, Object)
*/
public void set(final String key, final String value) {
if (this.configMap.containsKey(key))
throw new IllegalArgumentException("key has already been used");
this.configMap.put(key, value);
}
/**
* Returns the value of the key or <code>null</code> if the key is not set.
* @param key - the key
* @return - the value for the key or <code>null</code> if the key is not set.
* @see Map#get(java.lang.Object)
*/
public String get(final String key) {
return this.configMap.get(key);
}
/**
* @param key - a string key
* @return - <code>true</code> if the key is set, otherwise <code>false</code>
* @see Map#containsKey(java.lang.Object)
*/
public boolean contains(String key) {
return this.configMap.containsKey(key);
}
}

View File

@ -0,0 +1,77 @@
/**
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.lucene.gdata.server.registry.configuration;
/**
* Will be throw if an exception occures while injecting properties, a type or
* cast exception occures or a
* {@link org.apache.lucene.gdata.server.registry.configuration.Requiered}
* property is not available.
*
* @author Simon Willnauer
*
*/
public class InjectionException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 3559845601111510210L;
/**
* Constructs a new InjectionException
*/
public InjectionException() {
super();
}
/**
* Constructs a new InjectionException
*
* @param message -
* the exception message
*/
public InjectionException(String message) {
super(message);
}
/**
* Constructs a new InjectionException
*
* @param message -
* the exception message
* @param cause -
* the root cause of this exception
*/
public InjectionException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructs a new InjectionException
*
* @param cause -
* the root cause of this exception
*/
public InjectionException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,282 @@
/**
* 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.configuration;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
/**
* PropertyInjector is used to set member variables / properties of classes via
* <i>setter</i> methodes using the
* {@link org.apache.lucene.gdata.server.registry.configuration.ComponentConfiguration}
* class.
* <p>
* To populate a object with properties from a ComponentConfiguration instance
* the class or a superclass of the object to populate has to provide at least
* one setter method with a single parameter. The object to populate is set via
* the {@link PropertyInjector#setTargetObject} method. The class of the object
* will be analyzed for setter methodes having a "set" prefix in their method
* name. If one of the found setter methodes is annotated with
* {@link org.apache.lucene.gdata.server.registry.configuration.Requiered} this
* property is interpreted as a mandatory property. Mandatory properties must be
* available in the provided ComponentConfiguration, if not the injection will
* fail.<br>
* The
* {@link org.apache.lucene.gdata.server.registry.configuration.ComponentConfiguration}
* contains key / value pairs where the key must match the signature of the
* setter method without the 'set' prefix and must begin with a lower case
* character. <span>Key<code>bufferSize</code> does match a method signature
* of <code>setBufferSize</code></span> The type of the parameter will be
* reflected via the Reflection API and instanciated with the given value if
* possible.
* </p>
* <p>
* Setter methodes without a <code>Requiered</code> anntoation will be set if
* the property is present in the ComponentConfiguration
* </p>
* <p>This class does not support overloaded setter methodes.</p>
* @author Simon Willnauer
* @see org.apache.lucene.gdata.server.registry.configuration.Requiered
* @see org.apache.lucene.gdata.server.registry.configuration.ComponentConfiguration
*/
public class PropertyInjector {
private static final String SETTER_PREFIX = "set";
private Class targetClass;
private Object target;
private Map<String, Method> requieredProperties = new HashMap<String, Method>();
private Map<String, Method> optionalProperties = new HashMap<String, Method>();
/**
* Sets the object to be populated with the properties provided in the ComponentConfiguration.
* @param o - the object to populate
*/
public void setTargetObject(final Object o) {
if (o == null)
throw new IllegalArgumentException("TargetObject must not be null");
this.target = o;
this.targetClass = o.getClass();
try {
registerProperties(this.targetClass);
} catch (Exception e) {
throw new InjectionException("can access field -- "
+ e.getMessage(), e);
}
if (this.requieredProperties.isEmpty()
&& this.optionalProperties.isEmpty())
throw new InjectionException(
"Given type has no public setter methodes -- "
+ o.getClass().getName());
}
protected int getRequiredSize() {
return this.requieredProperties.size();
}
protected int getOptionalSize() {
return this.optionalProperties.size();
}
private void registerProperties(final Class clazz)
throws SecurityException, NoSuchFieldException {
if (clazz == null)
return;
Method[] methodes = clazz.getMethods();
for (int i = 0; i < methodes.length; i++) {
if (methodes[i].getName()
.startsWith(PropertyInjector.SETTER_PREFIX)) {
String methodName = methodes[i].getName();
String fieldName = getFieldName(methodName);
if (methodes[i].getAnnotation(Requiered.class) != null)
this.requieredProperties.put(fieldName, methodes[i]);
else
this.optionalProperties.put(fieldName, methodes[i]);
}
}
registerProperties(clazz.getSuperclass());
}
private String getFieldName(final String setterMethodName) {
// remove 'set' prefix --> first char as lowerCase
String retVal = setterMethodName.substring(3);
String firstLetter = retVal.substring(0, 1);
retVal = retVal.replaceFirst(firstLetter, firstLetter.toLowerCase());
return retVal;
}
/**
* Injects the properties stored in the <code>ComponentConfiguration</code>
* to the corresponding methodes of the target object
* @param bean - configuration bean containing all properties to set.
*
*/
public void injectProperties(final ComponentConfiguration bean) {
if (bean == null)
throw new IllegalArgumentException("bean must not be null");
if (this.target == null)
throw new IllegalStateException("target is not set -- null");
Set<Entry<String, Method>> requiered = this.requieredProperties
.entrySet();
// set requiered properties
for (Entry<String, Method> entry : requiered) {
if (!bean.contains(entry.getKey()))
throw new InjectionException(
"requiered property can not be set -- value not in configuration bean; Property: "
+ entry.getKey()
+ "for class "
+ this.targetClass.getName());
populate(bean, entry);
}
Set<Entry<String, Method>> optinal = this.optionalProperties.entrySet();
// set optional properties
for (Entry<String, Method> entry : optinal) {
if (bean.contains(entry.getKey()))
populate(bean, entry);
}
}
private void populate(ComponentConfiguration bean,
Entry<String, Method> entry) {
String value = bean.get(entry.getKey());
Method m = entry.getValue();
Class<?>[] parameterTypes = m.getParameterTypes();
if (parameterTypes.length > 1)
throw new InjectionException("Setter has more than one parameter "
+ m.getName() + " -- can not invoke method -- ");
Object parameter = null;
try {
parameter = createObject(value, parameterTypes[0]);
} catch (InjectionException e) {
throw new InjectionException(
"parameter object creation failed for method "
+ m.getName() + " in class: "
+ this.targetClass.getName(), e);
}
// only setters with one parameter are supported
Object[] parameters = { parameter };
try {
m.invoke(this.target, parameters);
} catch (Exception e) {
throw new InjectionException("Can not set value of type "
+ value.getClass().getName()
+ " -- can not invoke method -- " + e.getMessage(), e);
}
}
private Object createObject(String s, Class<?> clazz) {
try {
// if class is requested use s as fully qualified classname
if (clazz == Class.class)
return Class.forName(s);
// check for primitive type
if (clazz.isPrimitive())
clazz = getPrimitiveWrapper(clazz);
boolean defaultConst = false;
boolean stringConst = false;
Constructor[] constructors = clazz.getConstructors();
if (constructors.length == 0)
defaultConst = true;
for (int i = 0; i < constructors.length; i++) {
if (constructors[i].getParameterTypes().length == 0) {
defaultConst = true;
continue;
}
if (constructors[i].getParameterTypes().length == 1
&& constructors[i].getParameterTypes()[0]
.equals(String.class))
stringConst = true;
}
/*
* if there is a string constructor use the string as a parameter
*/
if (stringConst) {
Constructor constructor = clazz
.getConstructor(new Class[] { String.class });
return constructor.newInstance(new Object[] { s });
}
/*
* if no string const. but a default const -- use the string as a
* classname
*/
if (defaultConst)
return Class.forName(s).newInstance();
throw new InjectionException(
"Parameter can not be created -- no default or String constructor found for class "
+ clazz.getName());
} catch (Exception e) {
throw new InjectionException("can not create object for setter", e);
}
}
/**
* Sets all members to their default values and clears the internal used
* {@link Map} instances
*
* @see Map#clear()
*/
public void clear() {
this.target = null;
this.targetClass = null;
this.optionalProperties.clear();
this.requieredProperties.clear();
}
/*
* return the wrappertype for the given primitive type. Wrappers can be
* easily instanciated via reflection and will be boxed by the vm
*/
private static final Class getPrimitiveWrapper(Class primitive) {
if (primitive == Integer.TYPE)
return Integer.class;
if (primitive == Float.TYPE)
return Float.class;
if (primitive == Long.TYPE)
return Long.class;
if (primitive == Short.TYPE)
return Short.class;
if (primitive == Byte.TYPE)
return Byte.class;
if (primitive == Double.TYPE)
return Double.class;
if (primitive == Boolean.TYPE)
return Boolean.class;
return primitive;
}
}

View File

@ -0,0 +1,37 @@
/**
* 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.configuration;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* This annotation is used to define mandatory properties via their setter
* methodes. It will be present at runtime.
*
* @see org.apache.lucene.gdata.server.registry.configuration.PropertyInjector
* @see org.apache.lucene.gdata.server.registry.configuration.ComponentConfiguration
* @author Simon Willnauer
*
*/
@Target( { METHOD })
@Retention(value = RUNTIME)
public @interface Requiered {
//
}

View File

@ -0,0 +1,423 @@
/**
* 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.db4o;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.gdata.data.GDataAccount;
import org.apache.lucene.gdata.data.ServerBaseFeed;
import org.apache.lucene.gdata.server.registry.Component;
import org.apache.lucene.gdata.server.registry.ComponentType;
import org.apache.lucene.gdata.server.registry.Scope;
import org.apache.lucene.gdata.server.registry.ScopeVisitor;
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.db4o.DB4oStorage.DB4oEntry;
import org.apache.lucene.gdata.utils.Pool;
import org.apache.lucene.gdata.utils.PoolObjectFactory;
import org.apache.lucene.gdata.utils.SimpleObjectPool;
import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectServer;
import com.google.gdata.data.BaseEntry;
import com.google.gdata.data.BaseFeed;
/**
* The DB4o StorageContorller can be used as a persitence component for the
* gdata-server. To use DB4o a third party jar needs to added to the lib
* directory of the project. If the jar is not available in the lib directory
* all db4o dependent class won't be included in the build.
* <p>
* If the jar is present in the lib directory this class can be configured as a
* {@link org.apache.lucene.gdata.server.registry.ComponentType#STORAGECONTROLLER}
* via the <i>gdata-config.xml</i> file. For detailed config documentation see
* the wiki page.
* </p>
* <p>
* The DB4oController can run as a client or as a server to serve other running
* db4o clients in the network. To achive the best performance out of the db4o
* caching layer connections to the server will be reused in a connection pool.
* A connection will not be shared withing more than one thread. The controller
* release one connection per request and returns the connection when the
* request has been destroyed.
* </p>
* @see <a href="http://www.db4o.com">db4o website</a>
* @see org.apache.lucene.gdata.utils.Pool
*
*
* @author Simon Willnauer
*
*/
@Component(componentType = ComponentType.STORAGECONTROLLER)
@Scope(scope = Scope.ScopeType.REQUEST)
public class DB4oController implements StorageController, ScopeVisitor {
private static final Log LOG = LogFactory.getLog(DB4oController.class);
private final ThreadLocal<Storage> threadLocalStorage = new ThreadLocal<Storage>();
private Pool<ObjectContainer> containerPool;
private ObjectServer server;
private final IDGenerator idGenerator;
private boolean weakReferences;
private boolean runAsServer;
private int port;
private String filePath;
private String user;
private String password;
private String host;
private int containerPoolSize;
/**
* @throws NoSuchAlgorithmException
*
*/
public DB4oController() throws NoSuchAlgorithmException {
this.idGenerator = new IDGenerator(15);
}
ObjectContainer releaseContainer() {
return this.server.openClient();
}
/**
* @see org.apache.lucene.gdata.storage.StorageController#destroy()
*/
public void destroy() {
this.containerPool.destroy();
this.idGenerator.stopIDGenerator();
this.server.close();
}
/**
* @see org.apache.lucene.gdata.storage.StorageController#getStorage()
*/
public Storage getStorage() throws StorageException {
Storage retVal = this.threadLocalStorage.get();
if (retVal != null)
return retVal;
retVal = new DB4oStorage(this.containerPool.aquire(), this);
this.threadLocalStorage.set(retVal);
return retVal;
}
/**
* @see org.apache.lucene.gdata.server.registry.ServerComponent#initialize()
*/
public void initialize() {
if (LOG.isInfoEnabled())
LOG.info("Initialize " + this.toString());
Db4o.configure().objectClass(DB4oEntry.class).objectField("updated")
.indexed(true);
Db4o.configure().objectClass(BaseEntry.class).objectField("id")
.indexed(true);
Db4o.configure().objectClass(BaseFeed.class).objectField("id").indexed(
true);
Db4o.configure().objectClass(GDataAccount.class).objectField("name")
.indexed(true);
Db4o.configure().objectClass(ServerBaseFeed.class).cascadeOnDelete(
false);
Db4o.configure().objectClass(ServerBaseFeed.class)
.maximumActivationDepth(0);
Db4o.configure().objectClass(BaseFeed.class).minimumActivationDepth(10);
Db4o.configure().objectClass(BaseEntry.class)
.minimumActivationDepth(10);
Db4o.configure().objectClass(BaseFeed.class).cascadeOnDelete(true);
Db4o.configure().objectClass(DB4oEntry.class).cascadeOnDelete(true);
Db4o.configure().objectClass(GDataAccount.class).cascadeOnDelete(true);
Db4o.configure().weakReferences(this.weakReferences);
if (this.runAsServer) {
this.server = Db4o.openServer(this.filePath, this.port);
this.server.grantAccess(this.user, this.password);
} else {
InvocationHandler handler = new ObjectServerDecorator(this.user,
this.password, this.host, this.port);
this.server = (ObjectServer) Proxy.newProxyInstance(this.getClass()
.getClassLoader(), new Class[] { ObjectServer.class },
handler);
}
PoolObjectFactory<ObjectContainer> factory = new ObjectContinerFactory(
this.server);
this.containerPool = new SimpleObjectPool<ObjectContainer>(
this.containerPoolSize, factory);
try {
createAdminAccount();
} catch (StorageException e) {
e.printStackTrace();
}
}
private void createAdminAccount() throws StorageException {
GDataAccount adminAccount = GDataAccount.createAdminAccount();
visiteInitialize();
Storage sto = this.getStorage();
try {
sto.getAccount(adminAccount.getName());
} catch (Exception e) {
this.getStorage().storeAccount(adminAccount);
} finally {
visiteDestroy();
}
}
/**
* @see org.apache.lucene.gdata.storage.StorageController#releaseId()
*/
public String releaseId(){
try{
return this.idGenerator.getUID();
}catch (InterruptedException e) {
throw new StorageException("ID producer has been interrupted",e);
}
}
/**
* @see org.apache.lucene.gdata.server.registry.ScopeVisitor#visiteInitialize()
*/
public void visiteInitialize() {
if (LOG.isInfoEnabled())
LOG.info("Opened Storage -- request initialized");
Storage storage = this.threadLocalStorage.get();
if (storage != null) {
LOG.warn("Storage already opened");
return;
}
storage = new DB4oStorage(this.containerPool.aquire(), this);
this.threadLocalStorage.set(storage);
}
/**
* @see org.apache.lucene.gdata.server.registry.ScopeVisitor#visiteDestroy()
*/
public void visiteDestroy() {
Storage storage = this.threadLocalStorage.get();
if (storage == null) {
LOG.warn("no Storage opened -- threadlocal returned null");
return;
}
this.containerPool.release(((DB4oStorage)storage).getContainer());
this.threadLocalStorage.remove();
if (LOG.isInfoEnabled())
LOG.info("Closed Storage -- request destroyed");
}
private static class ObjectContinerFactory implements
PoolObjectFactory<ObjectContainer> {
private final ObjectServer server;
ObjectContinerFactory(final ObjectServer server) {
this.server = server;
}
/**
* @see org.apache.lucene.gdata.utils.PoolObjectFactory#getInstance()
*/
public ObjectContainer getInstance() {
return this.server.openClient();
}
/**
* @param type -
* object container to destroy (close)
* @see org.apache.lucene.gdata.utils.PoolObjectFactory#destroyInstance(Object)
*/
public void destroyInstance(ObjectContainer type) {
type.close();
}
}
/**
* @return Returns the filePath.
*/
public String getFilePath() {
return this.filePath;
}
/**
* @param filePath
* The filePath to set.
*/
public void setFilePath(String filePath) {
this.filePath = filePath;
}
/**
* @return Returns the host.
*/
public String getHost() {
return this.host;
}
/**
* @param host
* The host to set.
*/
@Requiered
public void setHost(String host) {
this.host = host;
}
/**
* @return Returns the password.
*/
public String getPassword() {
return this.password;
}
/**
* @param password
* The password to set.
*/
@Requiered
public void setPassword(String password) {
this.password = password;
}
/**
* @return Returns the port.
*/
public int getPort() {
return this.port;
}
/**
* @param port
* The port to set.
*/
@Requiered
public void setPort(int port) {
this.port = port;
}
/**
* @return Returns the runAsServer.
*/
public boolean isRunAsServer() {
return this.runAsServer;
}
/**
* @param runAsServer
* The runAsServer to set.
*/
@Requiered
public void setRunAsServer(boolean runAsServer) {
this.runAsServer = runAsServer;
}
/**
* @return Returns the user.
*/
public String getUser() {
return this.user;
}
/**
* @param user
* The user to set.
*/
@Requiered
public void setUser(String user) {
this.user = user;
}
/**
* @return Returns the weakReferences.
*/
public boolean isUseWeakReferences() {
return this.weakReferences;
}
/**
* @param weakReferences
* The weakReferences to set.
*/
@Requiered
public void setUseWeakReferences(boolean weakReferences) {
this.weakReferences = weakReferences;
}
/**
* @return Returns the containerPoolSize.
*/
public int getContainerPoolSize() {
return this.containerPoolSize;
}
/**
* @param containerPoolSize
* The containerPoolSize to set.
*/
@Requiered
public void setContainerPoolSize(int containerPoolSize) {
this.containerPoolSize = containerPoolSize < 1 ? 1 : containerPoolSize;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder(this.getClass().getName())
.append(" ");
builder.append("host: ").append(this.host).append(" ");
builder.append("port: ").append(this.port).append(" ");
builder.append("pool size: ").append(this.containerPoolSize)
.append(" ");
builder.append("runs as server: ").append(this.runAsServer).append(" ");
builder.append("use weak references: ").append(this.weakReferences)
.append(" ");
builder.append("user: ").append(this.user).append(" ");
builder.append("password length: ").append(
this.password == null ? "no password" : this.password.length())
.append(" ");
return builder.toString();
}
}

View File

@ -0,0 +1,788 @@
/**
* 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.db4o;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.storage.ModificationConflictException;
import org.apache.lucene.gdata.storage.Storage;
import org.apache.lucene.gdata.storage.StorageController;
import org.apache.lucene.gdata.storage.StorageException;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Query;
import com.google.gdata.data.BaseEntry;
import com.google.gdata.data.BaseFeed;
import com.google.gdata.data.DateTime;
/**
*
* Storage implementaion for the DB4o storage component
* @author Simon Willnauer
*
*/
public class DB4oStorage implements Storage {
private static final Log LOG = LogFactory.getLog(DB4oStorage.class);
private final ObjectContainer container;
private final StorageController controller;
private final List<String> semaphore = new ArrayList<String>();
protected DB4oStorage(final ObjectContainer container,
StorageController controller) {
this.container = container;
this.controller = controller;
}
private void createSemaphore(String key)
throws ModificationConflictException {
this.semaphore.add(key);
if (this.container.ext().setSemaphore(key, 0))
return;
throw new ModificationConflictException(
"can not create semaphore for key -- " + key);
}
private void releaseAllSemaphore() {
for (String key : this.semaphore) {
this.container.ext().releaseSemaphore(key);
}
this.semaphore.clear();
}
private void releaseSemaphore(String key) {
if (this.semaphore.contains(key)) {
this.container.ext().releaseSemaphore(key);
this.semaphore.remove(key);
}
}
/**
* @see org.apache.lucene.gdata.storage.Storage#storeEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
*/
public BaseEntry storeEntry(ServerBaseEntry entry) throws StorageException {
if (entry == null)
throw new StorageException("Can not store entry -- is null");
if (entry.getFeedId() == null)
throw new StorageException("can not store entry -- feed id is null");
if (LOG.isDebugEnabled())
LOG.debug("Storing entry for feed: " + entry.getFeedId());
BaseFeed<BaseFeed, BaseEntry> feed = getFeedOnly(entry.getFeedId());
refreshPersistentObject(feed);
try {
StringBuilder idBuilder = new StringBuilder(entry.getFeedId());
idBuilder.append(this.controller.releaseId());
entry.setId(idBuilder.toString());
} catch (StorageException e) {
LOG.error("Can not create uid for entry -- " + e.getMessage(), e);
throw new StorageException("Can not create uid for entry -- "
+ e.getMessage(), e);
}
setUpdated(entry, feed);
DB4oEntry intEntry = new DB4oEntry();
intEntry.setEntry(entry.getEntry());
intEntry.setUpdateTime(entry.getUpdated().getValue());
intEntry.setFeedId(feed.getId());
intEntry.setVersion(entry.getVersion());
try {
this.container.set(feed);
this.container.set(intEntry);
this.container.commit();
} catch (Exception e) {
LOG
.error("Error occured on persisting changes -- rollback changes");
this.container.rollback();
throw new StorageException("Can not persist changes -- "
+ e.getMessage(), e);
}
if (LOG.isInfoEnabled())
LOG.info("Stored Entry for entryID: " + entry.getId()
+ " -- feedID: " + entry.getFeedId());
return entry.getEntry();
}
private void setUpdated(ServerBaseEntry entry, DB4oEntry intEntry) {
if (entry.getUpdated().compareTo(intEntry.getEntry().getUpdated()) <= 0) {
if (LOG.isDebugEnabled())
LOG
.debug("Set new UpdateTime to entry new entry time is less or equal the time of the stored entry -- old Entry: "
+ intEntry.getEntry().getUpdated()
+ "; new Entry: " + entry.getUpdated());
entry.setUpdated(new DateTime(System.currentTimeMillis(), entry
.getUpdated().getTzShift()));
}
}
private void setUpdated(ServerBaseEntry entry,
BaseFeed<BaseFeed, BaseEntry> feed) {
if (entry.getUpdated() != null){
long timeInMilli = entry.getUpdated().getValue();
int tzShift = entry.getUpdated().getTzShift();
feed.setUpdated(new DateTime(timeInMilli, tzShift));
}
else{
int timezone = 0;
if(feed.getUpdated() != null){
timezone = feed.getUpdated().getTzShift();
}
long timeInMilli = System.currentTimeMillis();
entry.setUpdated(new DateTime(timeInMilli,timezone));
feed.setUpdated(new DateTime(timeInMilli,timezone));
}
}
/**
* @see org.apache.lucene.gdata.storage.Storage#deleteEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
*/
public void deleteEntry(ServerBaseEntry entry) throws StorageException {
if (entry == null)
throw new StorageException("Can not delete entry -- is null");
if (entry.getFeedId() == null)
throw new StorageException(
"can not delete entry -- feed id is null");
if (entry.getId() == null)
throw new StorageException("Can not delete entry -- id is null");
if (LOG.isDebugEnabled())
LOG.debug("delete entry for feed: " + entry.getFeedId()
+ " entry ID: " + entry.getId());
DB4oEntry persistentEntry = getInternalEntry(entry.getId());
// lock the entry to prevent concurrent access
createSemaphore(entry.getId());
refreshPersistentObject(persistentEntry);
if(persistentEntry.getVersion() != entry.getVersion())
throw new ModificationConflictException(
"Current version does not match given version -- currentVersion: "+persistentEntry.getVersion()+"; given Version: "+entry.getVersion() );
BaseFeed<BaseFeed, BaseEntry> feed = getFeedOnly(entry.getFeedId());
refreshPersistentObject(feed);
DateTime time = DateTime.now();
if (persistentEntry.getEntry().getUpdated() != null)
time.setTzShift(persistentEntry.getEntry().getUpdated().getTzShift());
feed.setUpdated(time);
try {
//delete the entry
this.container.delete(persistentEntry.getEntry());
this.container.delete(persistentEntry);
this.container.set(feed);
this.container.commit();
} catch (Exception e) {
LOG
.error("Error occured on persisting changes -- rollback changes");
this.container.rollback();
throw new StorageException("Can not persist changes -- "
+ e.getMessage(), e);
} finally {
releaseSemaphore(entry.getId());
}
}
/**
* @see org.apache.lucene.gdata.storage.Storage#updateEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
*/
public BaseEntry updateEntry(ServerBaseEntry entry) throws StorageException {
if (entry == null)
throw new StorageException("Can not update entry -- is null");
if (entry.getFeedId() == null)
throw new StorageException(
"can not delete entry -- feed id is null");
if (entry.getId() == null)
throw new StorageException("Can not delete entry -- id is null");
DB4oEntry persistentEntry = getInternalEntry(entry.getId());
// lock the entry to prevent concurrent access
createSemaphore(entry.getId());
refreshPersistentObject(persistentEntry);
if(persistentEntry.getVersion() != entry.getVersion())
throw new ModificationConflictException(
"Current version does not match given version -- currentVersion: "+persistentEntry.getVersion()+"; given Version: "+entry.getVersion() );
setUpdated(entry, persistentEntry);
BaseFeed<BaseFeed, BaseEntry> feed = getFeedOnly(entry.getFeedId());
refreshPersistentObject(feed);
BaseEntry retVal = entry.getEntry();
DB4oEntry newEntry = new DB4oEntry();
newEntry.setEntry(retVal);
newEntry.setUpdateTime(entry.getUpdated().getValue());
newEntry.setFeedId(feed.getId());
// increment Version
newEntry.setVersion((entry.getVersion())+1);
setUpdated(entry, feed);
try {
this.container.set(feed);
this.container.set(newEntry);
this.container.delete(persistentEntry.getEntry());
this.container.delete(persistentEntry);
this.container.commit();
} catch (Exception e) {
LOG
.error("Error occured on persisting changes -- rollback changes");
this.container.rollback();
throw new StorageException("Can not persist changes -- "
+ e.getMessage(), e);
} finally {
releaseSemaphore(entry.getId());
}
return retVal;
}
/**
* @see org.apache.lucene.gdata.storage.Storage#getFeed(org.apache.lucene.gdata.data.ServerBaseFeed)
*/
@SuppressWarnings("unchecked")
public BaseFeed getFeed(ServerBaseFeed feed) throws StorageException {
if (feed.getId() == null)
throw new StorageException("can not get feed -- feed id is null");
if (feed.getStartIndex() < 1)
feed.setStartIndex(1);
if (feed.getItemsPerPage() < 0)
feed.setItemsPerPage(25);
if (LOG.isInfoEnabled())
LOG.info("Fetching feed for feedID: " + feed.getId()
+ "; startindex: " + feed.getStartIndex()
+ "; items per page: " + feed.getItemsPerPage());
BaseFeed<BaseFeed, BaseEntry> persistentFeed = getFeedOnly(feed.getId());
/*
* prevent previously added entries in long running storage instances
*/
clearDynamicElements(persistentFeed);
Query query = this.container.query();
query.constrain(DB4oEntry.class);
query.descend("feedId").constrain(feed.getId()).equal();
query.descend("updateTime").orderDescending();
ObjectSet<DB4oEntry> set = query.execute();
int size = set.size();
if (size < feed.getStartIndex()) {
if (LOG.isDebugEnabled())
LOG.debug("no entries found for feed constrain -- feedID: "
+ feed.getId() + "; startindex: "
+ feed.getStartIndex() + "; items per page: "
+ feed.getItemsPerPage());
return persistentFeed;
}
int start = feed.getStartIndex() - 1;
int items = start + feed.getItemsPerPage();
if (items > size)
items = size;
List<DB4oEntry> sublist = set.subList(start, items);
for (DB4oEntry entry : sublist) {
persistentFeed.getEntries().add(clearDynamicElements(entry.getEntry()));
}
return persistentFeed;
}
@SuppressWarnings("unchecked")
private BaseFeed<BaseFeed, BaseEntry> getFeedOnly(String feedId)
throws StorageException {
Query query = this.container.query();
query.constrain(BaseFeed.class);
query.descend("id").constrain(feedId).equal();
ObjectSet set = query.execute();
if (set.size() > 1)
throw new StorageException("Query for feed id " + feedId
+ " returns more than one result");
if (set.hasNext())
return (BaseFeed<BaseFeed, BaseEntry>) set.next();
throw new StorageException("can not find feed for given feed id -- "
+ feedId);
}
private ObjectSet getEnriesForFeedID(String feedId) {
Query query = this.container.query();
query.constrain(DB4oEntry.class);
query.descend("feedId").constrain(feedId).equal();
return query.execute();
}
/**
* @see org.apache.lucene.gdata.storage.Storage#getEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
*/
public BaseEntry getEntry(ServerBaseEntry entry) throws StorageException {
if (entry == null)
throw new StorageException("can not retrieve entry -- is null");
if (entry.getId() == null)
throw new StorageException("can not retrieve entry -- id is null");
if (LOG.isInfoEnabled())
LOG.info("Retrieving entry for entryID: " + entry.getId());
return clearDynamicElements(getInternalEntry(entry.getId()).getEntry());
}
@SuppressWarnings("unchecked")
private DB4oEntry getInternalEntry(String id) throws StorageException {
Query query = this.container.query();
query.constrain(DB4oEntry.class);
query.descend("entry").descend("id").constrain(id).equal();
ObjectSet<DB4oEntry> resultSet = query.execute();
if (resultSet.size() > 1)
throw new StorageException(
"Entry query returned not a unique result");
if (resultSet.hasNext())
return resultSet.next();
throw new StorageException("no entry with entryID: " + id
+ " stored -- query returned no result");
}
/**
* @see org.apache.lucene.gdata.storage.Storage#storeAccount(org.apache.lucene.gdata.data.GDataAccount)
*/
public void storeAccount(GDataAccount account) throws StorageException {
if (account == null)
throw new StorageException("can not store account -- is null");
if (account.getName() == null)
throw new StorageException("can not store account -- name is null");
if (account.getPassword() == null)
throw new StorageException(
"can not store account -- password is null");
try {
getAccount(account.getName());
throw new IllegalStateException("account with accountname: "
+ account.getName() + " already exists");
} catch (IllegalStateException e) {
throw new StorageException("Account already exists");
} catch (StorageException e) {
if (LOG.isDebugEnabled())
LOG
.debug("checked account for existence -- does not exist -- store account");
}
try {
this.container.set(account);
this.container.commit();
} catch (Exception e) {
LOG
.error("Error occured on persisting changes -- rollback changes");
this.container.rollback();
throw new StorageException("Can not persist changes -- "
+ e.getMessage(), e);
}
if (LOG.isInfoEnabled())
LOG.info("Stored account: " + account);
}
/**
* @see org.apache.lucene.gdata.storage.Storage#updateAccount(org.apache.lucene.gdata.data.GDataAccount)
*/
public void updateAccount(GDataAccount account) throws StorageException {
if (account == null)
throw new StorageException("can not update account -- is null");
if (account.getName() == null)
throw new StorageException("can not update account -- name is null");
if (account.getPassword() == null)
throw new StorageException(
"can not update account -- password is null");
GDataAccount persitentAccount = getAccount(account.getName());
refreshPersistentObject(persitentAccount);
try {
this.container.set(account);
this.container.delete(persitentAccount);
this.container.commit();
} catch (Exception e) {
LOG
.error("Error occured on persisting changes -- rollback changes");
this.container.rollback();
throw new StorageException("Can not persist changes -- "
+ e.getMessage(), e);
}
}
/**
* @see org.apache.lucene.gdata.storage.Storage#deleteAccount(java.lang.String)
*/
public void deleteAccount(String accountname) throws StorageException {
if (accountname == null)
throw new StorageException(
"can not delete account -- accountname is null");
GDataAccount account = this.getAccount(accountname);
refreshPersistentObject(account);
if (LOG.isInfoEnabled())
LOG.info("delete account -- account name: " + accountname);
try {
this.container.delete(account);
this.container.commit();
} catch (Exception e) {
LOG
.error("Error occured on persisting changes -- rollback changes");
this.container.rollback();
throw new StorageException("Can not persist changes -- "
+ e.getMessage(), e);
}
}
/**
* @see org.apache.lucene.gdata.storage.Storage#storeFeed(org.apache.lucene.gdata.data.ServerBaseFeed,
* java.lang.String)
*/
public void storeFeed(ServerBaseFeed feed, String accountname)
throws StorageException {
if (feed == null)
throw new StorageException("Can not store feed -- is null");
if (feed.getId() == null)
throw new StorageException("Can not store feed -- id is null");
if(feed.getServiceType() == null)
throw new StorageException("Can not store feed -- service type is null");
if(accountname == null)
throw new StorageException("Account name is null");
Query query = this.container.query();
query.constrain(ServerBaseFeed.class);
query.descend("feed").descend("id").constrain(feed.getId()).equal();
ObjectSet set = query.execute();
if (set.hasNext())
throw new StorageException("feed with feedID " + feed.getId()
+ " is already stored");
GDataAccount account = getAccount(accountname);
refreshPersistentObject(account);
feed.setAccount(account);
/*
* service config not requiered in db4o storage.
* Entries/Feeds don't have to be build from xml
*/
feed.setServiceConfig(null);
try {
this.container.set(feed);
this.container.commit();
} catch (Exception e) {
LOG
.error("Error occured on persisting changes -- rollback changes");
this.container.rollback();
throw new StorageException("Can not persist changes -- "
+ e.getMessage(), e);
}
}
/**
* @see org.apache.lucene.gdata.storage.Storage#deleteFeed(java.lang.String)
*/
public void deleteFeed(String feedId) throws StorageException {
if (feedId == null)
throw new StorageException("can not delete feed -- feed id is null");
Query query = this.container.query();
query.constrain(ServerBaseFeed.class);
query.descend("feed").descend("id").constrain(feedId).equal();
ObjectSet set = query.execute();
if (set.size() > 1)
throw new StorageException(
"Feed query returned not a unique result");
if (set.size() == 0)
throw new StorageException("no feed with feedID: " + feedId
+ " stored -- query returned no result");
ServerBaseFeed feed = (ServerBaseFeed) set.next();
refreshPersistentObject(feed);
ObjectSet entrySet = getEnriesForFeedID(feed.getId());
try {
this.container.delete(feed);
this.container.delete(feed.getFeed());
for (Object object : entrySet) {
refreshPersistentObject(object);
this.container.delete(object);
}
this.container.commit();
} catch (Exception e) {
LOG
.error("Error occured on persisting changes -- rollback changes");
this.container.rollback();
throw new StorageException("Can not persist changes -- "
+ e.getMessage(), e);
}
}
/**
* @see org.apache.lucene.gdata.storage.Storage#updateFeed(org.apache.lucene.gdata.data.ServerBaseFeed,
* java.lang.String)
*/
@SuppressWarnings("unchecked")
public void updateFeed(ServerBaseFeed feed, String accountname)
throws StorageException {
if (feed == null)
throw new StorageException("Can not update feed -- is null");
if (feed.getId() == null)
throw new StorageException("Can not update feed -- id is null");
if(feed.getServiceType() == null)
throw new StorageException("Can not update feed -- service type is null");
if(accountname == null)
throw new StorageException("Account name is null");
GDataAccount account = getAccount(accountname);
Query query = this.container.query();
query.constrain(ServerBaseFeed.class);
query.descend("feed").descend("id").constrain(feed.getId());
ObjectSet<ServerBaseFeed> set= query.execute();
if (set.size() > 1)
throw new StorageException("Query for feed id " + feed.getId()
+ " returns more than one result");
if (set.size() < 1)
throw new StorageException("can not find feed for given feed id -- "
+ feed.getId());
ServerBaseFeed result = set.next();
refreshPersistentObject(result);
BaseFeed oldFeed = result.getFeed();
result.setAccount(account);
result.setFeed(feed.getFeed());
try {
this.container.delete(oldFeed);
this.container.set(result);
this.container.commit();
} catch (Exception e) {
LOG
.error("Error occured on persisting changes -- rollback changes");
this.container.rollback();
throw new StorageException("Can not persist changes -- "
+ e.getMessage(), e);
}
}
/**
* @see org.apache.lucene.gdata.storage.Storage#getServiceForFeed(java.lang.String)
*/
@SuppressWarnings("unchecked")
public String getServiceForFeed(final String feedId) throws StorageException {
if(feedId == null)
throw new StorageException("can not get Service for feed -- feed id is null");
if(LOG.isInfoEnabled())
LOG.info("retriving Service for feed -- feed id: "+feedId);
Query query = this.container.query();
query.constrain(ServerBaseFeed.class);
query.descend("feed").descend("id").constrain(feedId);
ObjectSet<ServerBaseFeed> feed = query.execute();
if (feed.size() > 1)
throw new StorageException("Query for feed id " + feedId
+ " returns more than one result");
if (feed.size() < 1)
throw new StorageException("can not find feed for given feed id -- "
+ feedId);
ServerBaseFeed result = feed.next();
if(LOG.isInfoEnabled())
LOG.info("retrived Service for feed -- serviceType: "+result.getServiceType());
return result.getServiceType();
}
/**
* @see org.apache.lucene.gdata.storage.Storage#getAccount(java.lang.String)
*/
public GDataAccount getAccount(String accountName) throws StorageException {
if (accountName == null)
throw new StorageException(
"Can not get account -- accountname is null");
if (LOG.isInfoEnabled())
LOG.info("Retrieving account for account name: " + accountName);
Query query = this.container.query();
query.constrain(GDataAccount.class);
query.descend("name").constrain(accountName).equal();
ObjectSet set = query.execute();
if (set.size() > 1)
throw new StorageException(
"Account query returned not a unique result -- account name: "
+ accountName);
if (!set.hasNext())
throw new StorageException(
"No such account stored -- query returned not result for account name: "
+ accountName);
return (GDataAccount) set.next();
}
/**
* @see org.apache.lucene.gdata.storage.Storage#close()
*/
public void close() {
releaseAllSemaphore();
}
/**
* @see org.apache.lucene.gdata.storage.Storage#getAccountNameForFeedId(java.lang.String)
*/
public String getAccountNameForFeedId(String feedId)
throws StorageException {
if(feedId == null)
throw new StorageException("feed id is null");
GDataAccount account = getServerBaseFeed(feedId).getAccount();
if(account == null)
throw new IllegalStateException("No account stored with feed -- feedID: "+feedId);
return account.getName();
}
/**
* @see org.apache.lucene.gdata.storage.Storage#getEntryLastModified(java.lang.String, java.lang.String)
*/
public Long getEntryLastModified(String entryId, final String feedId)
throws StorageException {
if(entryId == null)
throw new StorageException("Entry ID is null");
return new Long(getInternalEntry(entryId).getUpdateTime());
}
@SuppressWarnings("unchecked")
private ServerBaseFeed getServerBaseFeed(String feedId)throws StorageException{
Query query = this.container.query();
query.constrain(ServerBaseFeed.class);
query.descend("feed").descend("id").constrain(feedId);
ObjectSet<ServerBaseFeed> feed = query.execute();
if (feed.size() > 1)
throw new StorageException("Query for feed id " + feedId
+ " returns more than one result");
if (feed.size() < 1)
throw new StorageException("can not find feed for given feed id -- "
+ feedId);
return feed.next();
}
/*
* !Caution! -- could instanciate a lot of objects if used with certain classes!!
* refreshs a persistend object with a depth of 100
*
*/
private void refreshPersistentObject(Object o){
this.container.ext().refresh(o,100);
}
/**
* @see org.apache.lucene.gdata.storage.Storage#getFeedLastModified(java.lang.String)
*/
public Long getFeedLastModified(String feedId) throws StorageException {
if(feedId == null)
throw new StorageException("can not get last modified -- id is null");
ServerBaseFeed feed = getServerBaseFeed(feedId);
return new Long(feed.getUpdated().getValue());
}
private BaseEntry clearDynamicElements(BaseEntry entry){
this.container.ext().refresh(entry.getLinks(), 2);
return entry;
}
private BaseFeed clearDynamicElements(BaseFeed feed){
this.container.ext().refresh(feed.getLinks(), 2);
feed.getEntries().clear();
return feed;
}
ObjectContainer getContainer(){
return this.container;
}
static class DB4oEntry {
private BaseEntry entry;
private int version;
private String feedId;
private long updateTime;
/**
* @return Returns the entry.
*/
protected BaseEntry getEntry() {
return this.entry;
}
/**
* @param entry
* The entry to set.
*/
protected void setEntry(BaseEntry entry) {
this.entry = entry;
}
/**
* @return Returns the feed.
*/
protected String getFeedId() {
return this.feedId;
}
/**
* @param feed
* The feed to set.
*/
protected void setFeedId(String feed) {
this.feedId = feed;
}
/**
* @return Returns the updateTime.
*/
protected long getUpdateTime() {
return this.updateTime;
}
/**
* @param updateTime
* The updateTime to set.
*/
protected void setUpdateTime(long updateTime) {
this.updateTime = updateTime;
}
/**
* @return Returns the version.
*/
public int getVersion() {
return this.version;
}
/**
* @param version The version to set.
*/
public void setVersion(int version) {
this.version = version;
if(this.entry != null)
this.entry.setVersionId(""+this.version);
}
}
}

View File

@ -0,0 +1,69 @@
/**
* 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.db4o;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import com.db4o.Db4o;
import com.db4o.ObjectServer;
/**
* @author Simon Willnauer
*
*/
public class ObjectServerDecorator implements InvocationHandler {
private final int port;
private final String user;
private final String password;
private final String host;
private Method openClient;
/**
*
*/
public ObjectServerDecorator(String user, String password, String host, int port) {
this.user = user;
this.password = password;
this.host = host;
this.port = port;
try {
this.openClient = ObjectServer.class.getMethod("openClient",new Class[]{});
} catch (Exception e) {
//ignore method is visible
e.printStackTrace();
}
}
/**
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
if(arg1.equals(this.openClient)){
return Db4o.openClient(this.host,this.port, this.user, this.password);
}
Class clazz = arg1.getReturnType();
if(!clazz.isPrimitive())
return null;
if(clazz == Boolean.TYPE)
return false;
return 0;
}
}

View File

@ -0,0 +1,10 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Simon Willnauer">
</head>
<body>
DB4o storage implementation (needs third patry jar) <a href="http://www.db4o.com">DB4o Website</a>
</body>
</html>

View File

@ -0,0 +1,44 @@
package org.apache.lucene.gdata.server.registry.configuration;
import junit.framework.TestCase;
public class TestConfigurationBean extends TestCase {
private ComponentConfiguration bean;
protected void setUp() throws Exception {
super.setUp();
this.bean = new ComponentConfiguration();
}
protected void tearDown() throws Exception {
super.tearDown();
}
/*
* Test method for
* 'org.apache.lucene.gdata.server.registry.configuration.ConfigurationBean.set(String,
* String)'
*/
public void testSet() {
this.bean.set("field", "value");
try {
this.bean.set("field", "value");
fail("field already set");
} catch (IllegalArgumentException e) {
//
}
assertEquals("value", this.bean.get("field"));
}
/*
* Test method for
* 'org.apache.lucene.gdata.server.registry.configuration.ConfigurationBean.get(String)'
*/
public void testGet() {
assertNull(this.bean.get("field"));
this.bean.set("field", "value");
assertEquals("value", this.bean.get("field"));
}
}

View File

@ -0,0 +1,177 @@
package org.apache.lucene.gdata.server.registry.configuration;
import junit.framework.TestCase;
public class TestPropertyInjector extends TestCase {
private PropertyInjector injector;
protected void setUp() throws Exception {
super.setUp();
this.injector = new PropertyInjector();
}
protected void tearDown() throws Exception {
super.tearDown();
}
/*
* Test method for
* 'org.apache.lucene.gdata.server.registry.configuration.PropertyInjector.setTargetObject(Object)'
*/
public void testSetTargetObject() {
try {
this.injector.setTargetObject(null);
fail("must not be null");
} catch (IllegalArgumentException e) {
// TODO: handle exception
}
try {
this.injector.setTargetObject(new Object());
fail("no getter or setter methodes");
} catch (InjectionException e) {
// TODO: handle exception
}
this.injector.setTargetObject(new TestBean());
assertEquals(1,this.injector.getOptionalSize());
assertEquals(1,this.injector.getRequiredSize());
}
/*
* Test method for
* 'org.apache.lucene.gdata.server.registry.configuration.PropertyInjector.injectProperties(ConfigurationBean)'
*/
public void testInjectProperties() throws Exception {
ComponentConfiguration bean = new ComponentConfiguration();
bean.set("someValue","bla");
try{
this.injector.injectProperties(bean);
fail("target is not set");
}catch (IllegalStateException e) {
}
TestBean testBean = new TestBean();
this.injector.setTargetObject(testBean);
try{
this.injector.injectProperties(null);
fail("object is null");
}catch (IllegalArgumentException e) {
}
try{
this.injector.injectProperties(bean);
fail("requiered Property is not available in config bean");
}catch (InjectionException e) {
}
bean.set("test","fooBar");
bean.set("testClass","java.lang.Object");
this.injector.injectProperties(bean);
assertEquals("fooBar",testBean.getTest());
assertEquals(Object.class,testBean.getTestClass());
this.injector = new PropertyInjector();
SubTestBean subTestBean = new SubTestBean();
this.injector.setTargetObject(subTestBean);
bean.set("number","333");
this.injector.injectProperties(bean);
assertEquals("fooBar",subTestBean.getTest());
assertEquals(Object.class,subTestBean.getTestClass());
assertEquals(333,subTestBean.getNumber());
bean = new ComponentConfiguration();
bean.set("test","fooBar");
bean.set("number","333");
bean.set("wrapper","1.2");
subTestBean = new SubTestBean();
this.injector.setTargetObject(subTestBean);
this.injector.injectProperties(bean);
assertEquals("fooBar",subTestBean.getTest());
assertEquals(333,subTestBean.getNumber());
assertEquals(new Float(1.2),subTestBean.getWrapper());
}
public static class TestBean{
private String test;
private Class testClass;
/**
* @return Returns the test.
*/
public String getTest() {
return test;
}
/**
* @param test The test to set.
*/
@Requiered
public void setTest(String test) {
this.test = test;
}
/**
* @return Returns the testClass.
*/
public Class getTestClass() {
return testClass;
}
/**
* @param testClass The testClass to set.
*/
public void setTestClass(Class testClass) {
this.testClass = testClass;
}
}
public static class SubTestBean extends TestBean{
private int number;
private Float wrapper;
/**
* @return Returns the wrapper.
*/
public Float getWrapper() {
return wrapper;
}
/**
* @param wrapper The wrapper to set.
*/
public void setWrapper(Float wrapper) {
this.wrapper = wrapper;
}
/**
* @return Returns the number.
*/
public int getNumber() {
return number;
}
/**
* @param number The number to set.
*/
@Requiered
public void setNumber(int number) {
this.number = number;
}
}
}

View File

@ -0,0 +1,877 @@
package org.apache.lucene.gdata.storage.db4o;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
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.ProvidedServiceConfig;
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.Visitor;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Query;
import com.google.gdata.data.BaseEntry;
import com.google.gdata.data.BaseFeed;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.ExtensionProfile;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.util.common.xml.XmlWriter;
public class TestDb4oStorage extends TestCase {
private static final String FEEDID = "myFeed";
private static final String ACCOUNTNAME = "myAccount";
private static final String SERVICENAME = "myService";
DB4oController controller;
static volatile boolean fail = false;
protected void setUp() throws Exception {
this.controller = new DB4oController();
this.controller.setContainerPoolSize(2);
this.controller.setFilePath("test.yap");
this.controller.setRunAsServer(true);
this.controller.setPassword("");
this.controller.setUser("");
this.controller.setUseWeakReferences(true);
this.controller.setPort(0);
this.controller.initialize();
this.controller.visiteInitialize();
clearDB();
}
protected void tearDown() throws Exception {
clearDB();
fail = false;
this.controller.getStorage().close();
this.controller.visiteDestroy();
this.controller.destroy();
}
private void clearDB() {
ObjectContainer container = this.controller.releaseContainer();
ObjectSet set = container.get(new Object());
for (Object object : set) {
container.delete(object);
}
container.ext().purge();
container.close();
}
ObjectContainer getContainer() {
return this.controller.releaseContainer();
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.storeEntry(ServerBaseEntry)'
*/
@SuppressWarnings("unchecked")
public void testStoreEntry() throws StorageException {
Storage storage = this.controller.getStorage();
try {
ServerBaseEntry e = createServerBaseEntry();
storage.storeEntry(e);
fail("excption exp. for feed for the entry");
} catch (StorageException e) {
//
}
storeServerBaseFeed();
ServerBaseEntry e = createServerBaseEntry();
storage.storeEntry(e);
ServerBaseEntry e1 = createServerBaseEntry();
storage.storeEntry(e1);
storage = this.controller.getStorage();
Query query = getContainer().query();
query.constrain(BaseEntry.class);
query.descend("id").constrain(e.getId());
ObjectSet resultSet = query.execute();
assertEquals(1, resultSet.size());
BaseEntry storedEntry = (BaseEntry)resultSet.next();
assertEquals("1",storedEntry.getVersionId());
ServerBaseFeed bFeed = new ServerBaseFeed();
bFeed.setItemsPerPage(25);
bFeed.setId(FEEDID);
bFeed.setStartIndex(1);
BaseFeed<BaseFeed, BaseEntry> feed = storage.getFeed(bFeed);
assertEquals(2, feed.getEntries().size());
assertEquals(e.getId(), feed.getEntries().get(1).getId()); // last post
// ->
// previously
// created
assertEquals(e1.getId(), feed.getEntries().get(0).getId()); // first pos
// -> last
// created
assertEquals(feed.getUpdated(), feed.getEntries().get(0).getUpdated());
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.deleteEntry(ServerBaseEntry)'
*/
public void testDeleteEntry() throws StorageException, InterruptedException {
ObjectContainer container = getContainer();
storeServerBaseFeed();
Storage storage = this.controller.getStorage();
ServerBaseEntry e = createServerBaseEntry();
storage.storeEntry(e);
ServerBaseEntry e1 = createServerBaseEntry();
storage.storeEntry(e1);
storage.deleteEntry(e);
container.close();
container = getContainer();
Query query = container.query();
query.constrain(BaseEntry.class);
query.descend("id").constrain(e.getId());
ObjectSet resultSet = query.execute();
assertEquals(0, resultSet.size());
// #### test version matching
ServerBaseEntry eVersion = createServerBaseEntry();
storage.storeEntry(eVersion);
eVersion.setVersion(33);
try {
storage.deleteEntry(eVersion);
fail("version does not match");
} catch (Exception ex) {
// TODO: handle exception
}
storage = this.controller.getStorage();
storage.deleteEntry(e1);
container.close();
container = getContainer();
query = container.query();
query.constrain(BaseEntry.class);
query.descend("id").constrain(e1.getId());
resultSet = query.execute();
assertEquals(0, resultSet.size());
// ############ test concurrency
// ############ test concurrency
Object monitor = new Object();
AtomicBoolean reached = new AtomicBoolean(false);
MultiThreadEntryStub concuEntry = new MultiThreadEntryStub();
concuEntry.setId(System.currentTimeMillis() + "");
ProvidedServiceConfig conf = new ProvidedServiceConfig();
conf.setName(SERVICENAME);
concuEntry.setServiceConfig(conf);
concuEntry.setUpdated(DateTime.now());
concuEntry.setFeedId(FEEDID);
storage = this.controller.getStorage();
storage.storeEntry(concuEntry);
storage.close();
concuEntry.acceptGetVersionVisitor(getMonitorVisitor(monitor,reached));
Thread t1 = getDelThread(controller, concuEntry, false);
Thread t2 = getDelThread(controller, 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");
container.close();
}
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(StorageController c, ServerBaseEntry e,
boolean conflictExpected) {
Thread t1 = new Thread(new Runner(c, e, conflictExpected,
StorageOperation.DELETE));
t1.setPriority(Thread.MAX_PRIORITY);
return t1;
}
private Thread getUpdThread(StorageController c, ServerBaseEntry e,
boolean conflictExpected) {
Thread t1 = new Thread(new Runner(c, e, conflictExpected,
StorageOperation.UPDATE));
t1.setPriority(Thread.MAX_PRIORITY);
return t1;
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.updateEntry(ServerBaseEntry)'
*/
public void testUpdateEntry() throws StorageException, InterruptedException {
storeServerBaseFeed();
Storage storage = this.controller.getStorage();
ServerBaseEntry e = createServerBaseEntry();
ServerBaseEntry e1 = createServerBaseEntry();
try {
storage.updateEntry(e);
fail("entry does not exist");
} catch (StorageException ex) {
ex.printStackTrace();
}
storage.storeEntry(e);
storage = this.controller.getStorage();
storage.storeEntry(e1);
ServerBaseEntry e2 = createServerBaseEntry();
e2.setId(e.getId());
e2.setTitle(new PlainTextConstruct("new"));
e2.setUpdated(DateTime.now());
storage.updateEntry(e2);
ObjectContainer container = getContainer();
Query query = container.query();
query.constrain(BaseEntry.class);
query.descend("id").constrain(e.getId());
ObjectSet resultSet = query.execute();
assertEquals(1, resultSet.size());
BaseEntry result = (BaseEntry) resultSet.next();
assertEquals("new", result.getTitle().getPlainText());
assertEquals("2", result.getVersionId());
ServerBaseFeed bFeed = new ServerBaseFeed();
bFeed.setItemsPerPage(25);
bFeed.setId(FEEDID);
bFeed.setStartIndex(1);
storage = this.controller.getStorage();
BaseFeed<BaseFeed, BaseEntry> feed = storage.getFeed(bFeed);
assertEquals(2, feed.getEntries().size());
assertEquals(e.getId(), feed.getEntries().get(0).getId());
assertEquals(feed.getUpdated(), feed.getEntries().get(0).getUpdated());
storage = this.controller.getStorage();
storage.storeEntry(e);
e2.setVersion(5);
try {
storage.updateEntry(e2);
fail("version does not match");
} catch (Exception ex) {
// TODO: handle exception
}
// ############ test concurrency
Object monitor = new Object();
AtomicBoolean reached = new AtomicBoolean(false);
MultiThreadEntryStub concuEntry = new MultiThreadEntryStub();
concuEntry.setId(System.currentTimeMillis() + "");
ProvidedServiceConfig conf = new ProvidedServiceConfig();
conf.setName(SERVICENAME);
concuEntry.setServiceConfig(conf);
concuEntry.setUpdated(DateTime.now());
concuEntry.setFeedId(FEEDID);
storage = this.controller.getStorage();
storage.storeEntry(concuEntry);
storage.close();
concuEntry.acceptGetEntryVisitor(getMonitorVisitor(monitor,reached));
Thread t1 = getUpdThread(controller, concuEntry, false);
Thread t2 = getUpdThread(controller, 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");
container.close();
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.getFeed(ServerBaseFeed)'
*/
public void testGetFeed() throws StorageException {
storeServerBaseFeed();
Storage storage = this.controller.getStorage();
ServerBaseFeed feed = new ServerBaseFeed();
feed.setItemsPerPage(25);
feed.setStartIndex(1);
feed.setId(FEEDID);
BaseFeed result = storage.getFeed(feed);
assertNotNull(result);
assertEquals(0, result.getEntries().size());
List<String> idlist = new ArrayList<String>(30);
ServerBaseEntry e1 = null;
for (int i = 0; i < 30; i++) {
e1 = createServerBaseEntry();
storage.storeEntry(e1);
idlist.add(0, e1.getId());
}
String firstId = e1.getId();
storage = this.controller.getStorage();
result = storage.getFeed(feed);
assertNotNull(result);
assertEquals(25, result.getEntries().size());
for (int i = 0; i < 25; i++) {
assertEquals(idlist.get(i),
((BaseEntry) result.getEntries().get(i)).getId());
}
storage = this.controller.getStorage();
feed.setItemsPerPage(5);
result = storage.getFeed(feed);
assertNotNull(result);
assertEquals(5, result.getEntries().size());
for (int i = 0; i < 5; i++) {
assertEquals(idlist.get(i),
((BaseEntry) result.getEntries().get(i)).getId());
}
storage = this.controller.getStorage();
feed.setItemsPerPage(1);
feed.setStartIndex(1);
result = storage.getFeed(feed);
assertNotNull(result);
assertEquals(1, result.getEntries().size());
assertEquals(idlist.get(0), ((BaseEntry) result.getEntries().get(0))
.getId());
storage = this.controller.getStorage();
feed.setItemsPerPage(50);
feed.setStartIndex(28);
result = storage.getFeed(feed);
assertNotNull(result);
assertEquals(3, result.getEntries().size());
assertEquals(idlist.get(27), ((BaseEntry) result.getEntries().get(0))
.getId());
assertEquals(idlist.get(28), ((BaseEntry) result.getEntries().get(1))
.getId());
assertEquals(idlist.get(29), ((BaseEntry) result.getEntries().get(2))
.getId());
storage = this.controller.getStorage();
feed.setItemsPerPage(50);
feed.setStartIndex(30);
result = storage.getFeed(feed);
assertNotNull(result);
assertEquals(1, result.getEntries().size());
assertEquals(idlist.get(29), ((BaseEntry) result.getEntries().get(0))
.getId());
// assertNotSame(firstId,((BaseEntry)result.getEntries().get(0)).getId());
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.getEntry(ServerBaseEntry)'
*/
public void testGetEntry() throws StorageException {
storeServerBaseFeed();
Storage storage = this.controller.getStorage();
ServerBaseEntry e = createServerBaseEntry();
storage.storeEntry(e);
ServerBaseEntry e1 = createServerBaseEntry();
storage.storeEntry(e1);
storage = this.controller.getStorage();
BaseEntry result = storage.getEntry(e);
assertNotNull(result);
assertEquals(e.getId(), result.getId());
try {
e1.setId("hello");
result = storage.getEntry(e1);
fail("no such entry");
} catch (StorageException ex) {
ex.printStackTrace();
}
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.storeAccount(GDataAccount)'
*/
public void testStoreAccount() throws StorageException {
GDataAccount account = new GDataAccount();
account.setName("simon");
account.setPassword("somepass");
Storage storage = this.controller.getStorage();
storage.storeAccount(account);
ObjectContainer container = getContainer();
Query q = container.query();
q.constrain(GDataAccount.class);
q.descend("name").constrain(account.getName());
ObjectSet set = q.execute();
assertEquals(1, set.size());
assertEquals(account.getPassword(), ((GDataAccount) set.next())
.getPassword());
try {
storage.storeAccount(account);
fail("Account already stored");
} catch (Exception e) {
}
container.close();
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.updateAccount(GDataAccount)'
*/
public void testUpdateAccount() throws StorageException {
GDataAccount account = new GDataAccount();
account.setName("simon");
account.setPassword("somepass");
Storage storage = this.controller.getStorage();
try {
storage.updateAccount(account);
fail("Account does not exist");
} catch (Exception e) {
//
}
try {
storage.updateAccount(null);
fail("Account is null");
} catch (Exception e) {
//
}
storage.storeAccount(account);
ObjectContainer container = getContainer();
Query q = container.query();
q.constrain(GDataAccount.class);
q.descend("name").constrain(account.getName());
ObjectSet set = q.execute();
assertEquals(1, set.size());
assertEquals(account.getPassword(), ((GDataAccount) set.next())
.getPassword());
account = new GDataAccount();
account.setName("simon");
account.setPassword("newPass");
storage.updateAccount(account);
q = container.query();
q.constrain(GDataAccount.class);
q.descend("name").constrain(account.getName());
set = q.execute();
assertEquals(1, set.size());
assertEquals(account.getPassword(), ((GDataAccount) set.next())
.getPassword());
container.close();
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.deleteAccount(String)'
*/
public void testDeleteAccount() throws StorageException {
GDataAccount account = new GDataAccount();
account.setName("simon");
account.setPassword("somepass");
Storage storage = this.controller.getStorage();
storage.storeAccount(account);
ObjectContainer container = getContainer();
Query q = container.query();
q.constrain(GDataAccount.class);
q.descend("name").constrain(account.getName());
ObjectSet set = q.execute();
assertEquals(1, set.size());
storage.deleteAccount(account.getName());
q = container.query();
q.constrain(GDataAccount.class);
q.descend("name").constrain(account.getName());
set = q.execute();
assertEquals(0, set.size());
try {
storage.deleteAccount("notstored");
fail("account not stored");
} catch (Exception e) {
//
}
try {
storage.deleteAccount(null);
fail("name is null");
} catch (Exception e) {
//
}
container.close();
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.storeFeed(ServerBaseFeed,
* String)'
*/
public void testStoreFeed() throws StorageException {
ObjectContainer container = getContainer();
ServerBaseFeed feed = new ServerBaseFeed();
feed.setId(FEEDID);
ProvidedServiceConfig conf = new ProvidedServiceConfig();
conf.setName(SERVICENAME);
feed.setServiceConfig(conf);
Storage storage = this.controller.getStorage();
try {
storage.storeFeed(feed, ACCOUNTNAME);
fail("no accoutn stored");
} catch (Exception e) {
//
}
GDataAccount account = new GDataAccount();
account.setName(ACCOUNTNAME);
account.setPassword("somePass");
container.set(account);
container.commit();
container.close();
storage.storeFeed(feed, ACCOUNTNAME);
container = getContainer();
Query query = container.query();
query.constrain(ServerBaseFeed.class);
query.descend("feed").descend("id").constrain(FEEDID);
ObjectSet set = query.execute();
assertEquals(1, set.size());
assertEquals(feed.getId(), ((ServerBaseFeed) set.next()).getId());
container.close();
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.deleteFeed(String)'
*/
public void testDeleteFeed() throws StorageException {
ServerBaseFeed feed = new ServerBaseFeed();
feed.setId(FEEDID);
GDataAccount account = new GDataAccount();
account.setName(ACCOUNTNAME);
account.setPassword("somePass");
ObjectContainer container = getContainer();
container.set(account);
container.commit();
container.close();
Storage storage = this.controller.getStorage();
ProvidedServiceConfig conf = new ProvidedServiceConfig();
conf.setName(SERVICENAME);
feed.setServiceConfig(conf);
storage.storeFeed(feed, ACCOUNTNAME);
storage.deleteFeed(FEEDID);
container = getContainer();
Query query = container.query();
query.constrain(ServerBaseFeed.class);
query.descend("feed").descend("id").constrain(FEEDID);
ObjectSet set = query.execute();
assertEquals(0, set.size());
query = getContainer().query();
query.constrain(BaseFeed.class);
query.descend("id").constrain(FEEDID);
set = query.execute();
assertEquals(0, set.size());
container.close();
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.getServiceForFeed(String)'
*/
public void testGetServiceForFeed() throws StorageException {
ServerBaseFeed feed = new ServerBaseFeed();
ProvidedServiceConfig conf = new ProvidedServiceConfig();
conf.setName(SERVICENAME);
feed.setServiceConfig(conf);
feed.setId(FEEDID);
GDataAccount account = new GDataAccount();
account.setName(ACCOUNTNAME);
account.setPassword("somePass");
ObjectContainer container = getContainer();
container.set(account);
container.commit();
container.close();
Storage storage = this.controller.getStorage();
storage.storeFeed(feed, ACCOUNTNAME);
assertEquals(SERVICENAME, storage.getServiceForFeed(FEEDID));
try {
storage.getServiceForFeed(null);
fail("ID is null");
} catch (Exception e) {
//
}
try {
storage.getServiceForFeed("someOtherId");
fail("feed for id is not stored");
} catch (Exception e) {
//
}
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.getAccount(String)'
*/
public void testGetAccount() throws StorageException {
GDataAccount account = new GDataAccount();
account.setName(ACCOUNTNAME);
account.setPassword("somePass");
ObjectContainer container = getContainer();
container.set(account);
container.commit();
container.close();
Storage storage = this.controller.getStorage();
assertNotNull(storage.getAccount(ACCOUNTNAME));
assertEquals(account.getPassword(), storage.getAccount(ACCOUNTNAME)
.getPassword());
try {
storage.getAccount(null);
fail("accountname is null");
} catch (Exception e) {
//
}
try {
storage.getAccount("someOtherAccount");
fail("accountname is not stored");
} catch (Exception e) {
//
}
}
/*
* Test method for
* 'org.apache.lucene.gdata.storage.db4o.DB4oStorage.updateFeed(ServerBaseFeed,
* String)'
*/
public void testUpdateFeed() throws StorageException {
ObjectContainer container = getContainer();
ServerBaseFeed feed = new ServerBaseFeed();
ProvidedServiceConfig conf = new ProvidedServiceConfig();
conf.setName(SERVICENAME);
feed.setId(FEEDID);
feed.setServiceConfig(conf);
Storage storage = this.controller.getStorage();
GDataAccount account = new GDataAccount();
account.setName(ACCOUNTNAME);
account.setPassword("somePass");
container.set(account);
container.commit();
container.close();
storage.storeFeed(feed, ACCOUNTNAME);
assertNull(feed.getTitle());
ServerBaseFeed feedU = new ServerBaseFeed();
feedU.setServiceConfig(conf);
feedU.setId(FEEDID);
feedU.setTitle(new PlainTextConstruct("someText"));
storage.updateFeed(feedU, ACCOUNTNAME);
ServerBaseFeed requestFeed = new ServerBaseFeed();
requestFeed.setId(FEEDID);
assertNotNull(storage.getFeed(requestFeed));
assertEquals(feedU.getTitle(), storage.getFeed(requestFeed).getTitle());
try {
storage.updateFeed(null, ACCOUNTNAME);
fail("feed is null");
} catch (Exception e) {
//
}
try {
storage.updateFeed(feedU, null);
fail("accountname is null");
} catch (Exception e) {
//
}
try {
feedU.setServiceType(null);
storage.updateFeed(feedU, ACCOUNTNAME);
fail("servicetype is null");
} catch (Exception e) {
//
}
}
private static ServerBaseEntry createServerBaseEntry() {
ServerBaseEntry e = new ServerBaseEntry();
e.setId(System.currentTimeMillis() + "");
ProvidedServiceConfig conf = new ProvidedServiceConfig();
conf.setName(SERVICENAME);
e.setServiceConfig(conf);
e.setUpdated(DateTime.now());
e.setFeedId(FEEDID);
try {
Thread.sleep(2);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
return e;
}
private void storeServerBaseFeed() {
ServerBaseFeed f = new ServerBaseFeed();
ProvidedServiceConfig conf = new ProvidedServiceConfig();
conf.setName(SERVICENAME);
f.setServiceConfig(conf);
f.setId(System.currentTimeMillis() + "");
f.setId(FEEDID);
f.setUpdated(DateTime.now());
ObjectContainer con = this.controller.releaseContainer();
con.set(f);
con.commit();
con.close();
}
static class Runner implements Runnable {
Storage s;
StorageController c;
ServerBaseEntry e;
boolean expConf;
StorageOperation op;
public Runner(StorageController c, ServerBaseEntry e,
boolean expectConflict, StorageOperation op) {
this.c = c;
this.e = e;
this.expConf = expectConflict;
this.op = op;
}
public void run() {
try {
((DB4oController) this.c).visiteInitialize();
this.s = this.c.getStorage();
} catch (StorageException e1) {
e1.printStackTrace();
}
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;
} finally {
((DB4oController) this.c).visiteDestroy();
}
}
}
}