org.springextensions.db4o.Db4oTemplate.java Source code

Java tutorial

Introduction

Here is the source code for org.springextensions.db4o.Db4oTemplate.java

Source

/*
 * Copyright 2005-2011 the original author or authors.
 *
 * 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.springextensions.db4o;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Comparator;

import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.ext.Db4oDatabase;
import com.db4o.ext.Db4oException;
import com.db4o.ext.Db4oUUID;
import com.db4o.ext.ExtClient;
import com.db4o.ext.ExtObjectContainer;
import com.db4o.ext.ObjectInfo;
import com.db4o.ext.StoredClass;
import com.db4o.ext.SystemInfo;
import com.db4o.io.Storage;
import com.db4o.query.Predicate;
import com.db4o.query.Query;
import com.db4o.query.QueryComparator;
import com.db4o.reflect.ReflectClass;
import com.db4o.reflect.generic.GenericReflector;
import org.springframework.dao.DataAccessException;

/**
 * @author Costin Leau
 * @author olli
 */
public class Db4oTemplate extends Db4oAccessor implements Db4oOperations {

    private boolean exposeNativeContainer = false;

    public Db4oTemplate() {
    }

    public Db4oTemplate(ObjectContainer container) {
        setObjectContainer(container);
        afterPropertiesSet();
    }

    /**
     * @param exposeNativeContainer The exposeNativeContainer to set.
     */
    public void setExposeNativeContainer(boolean exposeNativeContainer) {
        this.exposeNativeContainer = exposeNativeContainer;
    }

    /**
     * @return Returns the exposeNativeContainer.
     */
    public boolean isExposeNativeContainer() {
        return exposeNativeContainer;
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#execute(org.springextensions.db4o.Db4oCallback)
     */
    public Object execute(Db4oCallback callback) throws DataAccessException {
        return execute(callback, isExposeNativeContainer());
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#execute(org.springextensions.db4o.Db4oCallback, boolean)
     */
    public Object execute(Db4oCallback callback, boolean exposeNativeContainer) throws DataAccessException {
        ObjectContainer cont = getObjectContainer();
        try {
            ObjectContainer container = (exposeNativeContainer ? cont : createContainerProxy(cont));
            return callback.doInDb4o(container);
        } catch (Db4oException ex) {
            throw convertDb4oAccessException(ex);
        } catch (RuntimeException ex) {
            RuntimeException convEx = convertDb4oAccessException(ex);
            // it's user specific
            if (convEx instanceof Db4oSystemException)
                throw ex;
            // it's a converted exception
            throw convEx;
        }
    }

    //
    // ObjectContainer interface methods
    //

    /**
     * @see org.springextensions.db4o.Db4oOperations#activate(java.lang.Object, int)
     */
    public void activate(final Object object, final int depth) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                container.activate(object, depth);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#deactivate(java.lang.Object, int)
     */
    public void deactivate(final Object object, final int depth) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                container.deactivate(object, depth);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#delete(java.lang.Object)
     */
    public void delete(final Object object) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                container.delete(object);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#queryByExample(java.lang.Object)
     */
    public <T> ObjectSet<T> queryByExample(final Object template) {
        return (ObjectSet<T>) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return container.queryByExample(template);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#query()
     */
    public Query query() {
        return (Query) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return container.query();
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#query(java.lang.Class)
     */
    public <TargetType> ObjectSet<TargetType> query(final Class<TargetType> clazz) {
        return (ObjectSet<TargetType>) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return container.query(clazz);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#query(com.db4o.query.Predicate)
     */
    public <TargetType> ObjectSet<TargetType> query(final Predicate<TargetType> predicate) {
        return (ObjectSet<TargetType>) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return container.query(predicate);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#query(com.db4o.query.Predicate, com.db4o.query.QueryComparator)
     */
    public <TargetType> ObjectSet<TargetType> query(final Predicate<TargetType> predicate,
            final QueryComparator<TargetType> comparator) {
        return (ObjectSet<TargetType>) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return container.query(predicate, comparator);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#query(com.db4o.query.Predicate, java.util.Comparator)
     */
    public <TargetType> ObjectSet<TargetType> query(final Predicate<TargetType> predicate,
            final Comparator<TargetType> comparator) {
        return (ObjectSet<TargetType>) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return container.query(predicate, comparator);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#store(java.lang.Object)
     */
    public void store(final Object object) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                container.store(object);
                return null;
            }
        }, true);
    }

    //
    // ExtObjectContainer interface methods
    //

    /**
     * @see org.springextensions.db4o.Db4oOperations#activate(java.lang.Object)
     */
    public void activate(final Object object) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                ((ExtObjectContainer) container).activate(object);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#deactivate(java.lang.Object)
     */
    public void deactivate(final Object object) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                ((ExtObjectContainer) container).deactivate(object);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#backup(java.lang.String)
     */
    public void backup(final String path) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                ((ExtObjectContainer) container).backup(path);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#backup(com.db4o.io.Storage, java.lang.String)
     */
    public void backup(final Storage targetStorage, final String path) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                ((ExtObjectContainer) container).backup(targetStorage, path);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#bind(java.lang.Object, long)
     */
    public void bind(final Object object, final long id) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                ((ExtObjectContainer) container).bind(object, id);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#descend(java.lang.Object, java.lang.String[])
     */
    public Object descend(final Object object, final String[] path) {
        return execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).descend(object, path);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#getByID(long)
     */
    public Object getByID(final long id) {
        return execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).getByID(id);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#getByUUID(com.db4o.ext.Db4oUUID)
     */
    public Object getByUUID(final Db4oUUID uuid) {
        return execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).getByUUID(uuid);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#getID(java.lang.Object)
     */
    public long getID(final Object object) {
        return (Long) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).getID(object);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#getObjectInfo(java.lang.Object)
     */
    public ObjectInfo getObjectInfo(final Object object) {
        return (ObjectInfo) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).getObjectInfo(object);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#identity()
     */
    public Db4oDatabase identity() {
        return (Db4oDatabase) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).identity();
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#isActive(java.lang.Object)
     */
    public boolean isActive(final Object object) {
        return (Boolean) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).isActive(object);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#isCached(long)
     */
    public boolean isCached(final long id) {
        return (Boolean) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).isCached(id);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#isClosed()
     */
    public boolean isClosed() {
        return (Boolean) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).isClosed();
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#isStored(java.lang.Object)
     */
    public boolean isStored(final Object object) {
        return (Boolean) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).isStored(object);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#knownClasses()
     */
    public ReflectClass[] knownClasses() {
        return (ReflectClass[]) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).knownClasses();
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#lock()
     */
    public Object lock() {
        return execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).lock();
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#openSession()
     */
    public ObjectContainer openSession() {
        return (ObjectContainer) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).openSession();
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#peekPersisted(java.lang.Object, int, boolean)
     */
    public <T> T peekPersisted(final T object, final int depth, final boolean committed) {
        return (T) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).peekPersisted(object, depth, committed);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#purge()
     */
    public void purge() {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                ((ExtObjectContainer) container).purge();
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#purge(java.lang.Object)
     */
    public void purge(final Object object) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                ((ExtObjectContainer) container).purge(object);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#reflector()
     */
    public GenericReflector reflector() {
        return (GenericReflector) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).reflector();
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#refresh(java.lang.Object, int)
     */
    public void refresh(final java.lang.Object object, final int depth) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                ((ExtObjectContainer) container).refresh(object, depth);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#releaseSemaphore(java.lang.String)
     */
    public void releaseSemaphore(final String name) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                ((ExtObjectContainer) container).releaseSemaphore(name);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#store(java.lang.Object, int)
     */
    public void store(final Object object, final int depth) {
        execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                ((ExtObjectContainer) container).store(object, depth);
                return null;
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#setSemaphore(java.lang.String, int)
     */
    public boolean setSemaphore(final String name, final int waitForAvailability) {
        return (Boolean) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).setSemaphore(name, waitForAvailability);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#storedClass(java.lang.Object)
     */
    public StoredClass storedClass(final Object clazz) {
        return (StoredClass) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).storedClass(clazz);
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#storedClasses()
     */
    public StoredClass[] storedClasses() {
        return (StoredClass[]) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).storedClasses();
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#systemInfo()
     */
    public SystemInfo systemInfo() {
        return (SystemInfo) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).systemInfo();
            }
        }, true);
    }

    /**
     * @see org.springextensions.db4o.Db4oOperations#version()
     */
    public long version() {
        return (Long) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtObjectContainer) container).version();
            }
        }, true);
    }

    //
    // ExtClient interface methods
    //

    public boolean isAlive() {
        return (Boolean) execute(new Db4oCallback() {
            public Object doInDb4o(ObjectContainer container) throws RuntimeException {
                return ((ExtClient) container).isAlive();
            }
        }, true);
    }

    //
    // Proxy
    //

    /**
     * Create a close-suppressing proxy for the given ObjectContainer.
     *
     * @param container the Db4o ObjectContainer to create a proxy for
     * @return the ObjectContainer proxy
     * @see com.db4o.ObjectContainer#close()
     */
    protected ObjectContainer createContainerProxy(ObjectContainer container) {
        // every db4o ObjectContainer always is an ExtObjectContainer
        Class intrface = ExtObjectContainer.class;
        if (container instanceof ExtClient) {
            // both Db4oClientServer.openClient() methods always return an ExtClient object
            intrface = ExtClient.class;
        }
        return (ObjectContainer) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { intrface },
                new CloseSuppressingInvocationHandler(container));
    }

    /**
     * Invocation handler that suppresses close calls on ObjectContainer.
     *
     * @see com.db4o.ObjectContainer#close()
     */
    private class CloseSuppressingInvocationHandler implements InvocationHandler {

        private final ObjectContainer target;

        public CloseSuppressingInvocationHandler(ObjectContainer target) {
            this.target = target;
        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (method.getName().equals("equals")) {
                // Only consider equal when proxies are identical.
                return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);
            } else if (method.getName().equals("hashCode")) {
                // Use hashCode of session proxy.
                return hashCode();
            } else if (method.getName().equals("close")) {
                // Handle close method: suppress, not valid.
                // tell the truth when returning the value.
                return Boolean.FALSE;
            }

            // invoke method on target container
            try {
                return method.invoke(this.target, args);
            } catch (InvocationTargetException ex) {
                throw ex.getTargetException();
            }
        }
    }

}