All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.api.client.extensions.jdo.JdoDataStoreFactory Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2013 Google Inc.
 *
 * 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 com.google.api.client.extensions.jdo;

import com.google.api.client.extensions.jdo.JdoDataStoreFactory.PrivateUtils.ComposedIdKey;
import com.google.api.client.util.IOUtils;
import com.google.api.client.util.Lists;
import com.google.api.client.util.Preconditions;
import com.google.api.client.util.Sets;
import com.google.api.client.util.store.AbstractDataStore;
import com.google.api.client.util.store.AbstractDataStoreFactory;
import com.google.api.client.util.store.DataStore;
import com.google.api.client.util.store.DataStoreUtils;

import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

/**
 * Thread-safe JDO implementation of a data store factory.
 *
 * @since 1.16
 * @author Yaniv Inbar
 * @deprecated Please use an alternative like Objectify.
 */
@Deprecated
public class JdoDataStoreFactory extends AbstractDataStoreFactory {

  /** Persistence manager factory. */
  private final PersistenceManagerFactory persistenceManagerFactory;

  public JdoDataStoreFactory(PersistenceManagerFactory persistenceManagerFactory) {
    this.persistenceManagerFactory = Preconditions.checkNotNull(persistenceManagerFactory);
  }

  @Override
  protected  DataStore createDataStore(String id) throws IOException {
    return new JdoDataStore(this, persistenceManagerFactory, id);
  }

  static class JdoDataStore extends AbstractDataStore {

    /** Lock on storing, loading and deleting a credential. */
    private final Lock lock = new ReentrantLock();

    /** Persistence manager factory. */
    private final PersistenceManagerFactory persistenceManagerFactory;

    JdoDataStore(JdoDataStoreFactory dataStore, PersistenceManagerFactory persistenceManagerFactory,
        String id) {
      super(dataStore, id);
      this.persistenceManagerFactory = persistenceManagerFactory;
    }

    public Set keySet() throws IOException {
      lock.lock();
      try {
        PersistenceManager persistenceManager = persistenceManagerFactory.getPersistenceManager();
        try {
          Query query = newAllKeysQuery(persistenceManager);
          try {
            Set result = Sets.newHashSet();
            for (JdoValue jdoValue : executeAllKeysQuery(query)) {
              result.add(jdoValue.getKey());
            }
            return Collections.unmodifiableSet(result);
          } finally {
            query.closeAll();
          }
        } finally {
          persistenceManager.close();
        }
      } finally {
        lock.unlock();
      }
    }

    public Collection values() throws IOException {
      lock.lock();
      try {
        PersistenceManager persistenceManager = persistenceManagerFactory.getPersistenceManager();
        try {
          Query query = newAllKeysQuery(persistenceManager);
          try {
            List result = Lists.newArrayList();
            for (JdoValue jdoValue : executeAllKeysQuery(query)) {
              result.add(jdoValue.deserialize());
            }
            return Collections.unmodifiableList(result);
          } finally {
            query.closeAll();
          }
        } finally {
          persistenceManager.close();
        }
      } finally {
        lock.unlock();
      }
    }

    public V get(String key) throws IOException {
      if (key == null) {
        return null;
      }
      lock.lock();
      try {
        PersistenceManager persistenceManager = persistenceManagerFactory.getPersistenceManager();
        try {
          Query query = newKeyQuery(persistenceManager);
          try {
            JdoValue jdoValue = executeKeyQuery(query, key);
            return jdoValue == null ? null : jdoValue.deserialize();
          } finally {
            query.closeAll();
          }
        } finally {
          persistenceManager.close();
        }
      } finally {
        lock.unlock();
      }
    }

    public JdoDataStore set(String key, V value) throws IOException {
      Preconditions.checkNotNull(key);
      Preconditions.checkNotNull(value);
      lock.lock();
      try {
        PersistenceManager persistenceManager = persistenceManagerFactory.getPersistenceManager();
        try {
          Query query = newKeyQuery(persistenceManager);
          try {
            JdoValue jdoValue = executeKeyQuery(query, key);
            if (jdoValue != null) {
              jdoValue.serialize(value);
            } else {
              jdoValue = new JdoValue(getId(), key, value);
              persistenceManager.makePersistent(jdoValue);
            }
          } finally {
            query.closeAll();
          }
        } finally {
          persistenceManager.close();
        }
      } finally {
        lock.unlock();
      }
      return this;
    }

    public DataStore delete(String key) throws IOException {
      if (key == null) {
        return this;
      }
      lock.lock();
      try {
        PersistenceManager persistenceManager = persistenceManagerFactory.getPersistenceManager();
        try {
          Query query = newKeyQuery(persistenceManager);
          try {
            JdoValue jdoValue = executeKeyQuery(query, key);
            if (jdoValue != null) {
              persistenceManager.deletePersistent(jdoValue);
            }
          } finally {
            query.closeAll();
          }
        } finally {
          persistenceManager.close();
        }
      } finally {
        lock.unlock();
      }
      return this;
    }

    public JdoDataStore clear() throws IOException {
      lock.lock();
      try {
        PersistenceManager persistenceManager = persistenceManagerFactory.getPersistenceManager();
        try {
          Query query = newAllKeysQuery(persistenceManager);
          try {
            persistenceManager.deletePersistentAll(executeAllKeysQuery(query));
          } finally {
            query.closeAll();
          }
        } finally {
          persistenceManager.close();
        }
      } finally {
        lock.unlock();
      }
      return this;
    }

    @Override
    public JdoDataStoreFactory getDataStoreFactory() {
      return (JdoDataStoreFactory) super.getDataStoreFactory();
    }

    @Override
    public String toString() {
      return DataStoreUtils.toString(this);
    }

    /**
     * Returns a new query for all keys.
     *
     * @param persistenceManager persistence manager
     * @return new query for all keys
     */
    Query newAllKeysQuery(PersistenceManager persistenceManager) {
      Query query = persistenceManager.newQuery(JdoValue.class);
      query.setFilter("id == idParam");
      query.declareParameters("String idParam");
      return query;
    }

    /**
     * Executes the query for all keys.
     *
     * @param allKeysQuery query for all keys
     * @return query result
     */
    @SuppressWarnings("unchecked")
    Collection executeAllKeysQuery(Query allKeysQuery) {
      return (Collection) allKeysQuery.execute(getId());
    }

    /**
     * Returns a new query for a given key.
     *
     * @param persistenceManager persistence manager
     * @return new new query for a given key
     */
    Query newKeyQuery(PersistenceManager persistenceManager) {
      Query query = persistenceManager.newQuery(JdoValue.class);
      query.setFilter("id == idParam && key == keyParam");
      query.declareParameters("String idParam, String keyParam");
      return query;
    }

    /**
     * Executes the query for a given key, and returns the {@link JdoValue}.
     *
     * @param keyQuery query for a given key
     * @param key key
     * @return found {@link JdoValue} or {@code null} for none found
     */
    @SuppressWarnings("unchecked")
    JdoValue executeKeyQuery(Query keyQuery, String key) {
      Collection queryResult = (Collection) keyQuery.execute(getId(), key);
      return queryResult.isEmpty() ? null : queryResult.iterator().next();
    }
  }

  /**
   * JDO value class that contains the key-value pair, as well as the data store ID.
   */
  @PersistenceCapable(objectIdClass = ComposedIdKey.class)
  static class JdoValue {

    /** Key. */
    @PrimaryKey
    @Persistent
    private String key;

    /** Data store ID. */
    @PrimaryKey
    @Persistent
    private String id;

    /** Byte array of value. */
    @Persistent
    private byte[] bytes;

    /* Required by JDO. */
    @SuppressWarnings("unused")
    JdoValue() {
    }

     JdoValue(String id, String key, V value) throws IOException {
      this.id = id;
      this.key = key;
      serialize(value);
    }

     void serialize(V value) throws IOException {
      bytes = IOUtils.serialize(value);
    }

     V deserialize() throws IOException {
      return IOUtils.deserialize(bytes);
    }

    String getKey() {
      return key;
    }
  }

  /**
   * Package private utilities class so the classes here isn't considered to be an external part of
   * the library. We need this because {@link ComposedIdKey} MUST be public because it is the
   * objectIdClass of {@link JdoValue}.
   */
  static class PrivateUtils {

    /**
     * See JDO :
     * PrimaryKey Classes for a reference.
     */
    public static class ComposedIdKey implements Serializable {

      private static final long serialVersionUID = 1L;

      /** Key. */
      public String key;

      /** Data store ID. */
      public String id;

      public ComposedIdKey() {
      }

      /**
       * @param value matches the result of toString()
       */
      public ComposedIdKey(String value) {
        StringTokenizer token = new StringTokenizer(value, "::");
        token.nextToken(); // className
        this.key = token.nextToken(); // key
        this.id = token.nextToken(); // id
      }

      @Override
      public boolean equals(Object obj) {
        if (obj == this) {
          return true;
        }
        if (!(obj instanceof ComposedIdKey)) {
          return false;
        }
        ComposedIdKey other = (ComposedIdKey) obj;
        return key.equals(other.key) && id.equals(other.id);
      }

      @Override
      public int hashCode() {
        return this.key.hashCode() ^ this.id.hashCode();
      }

      @Override
      public String toString() {
        return this.getClass().getName() + "::" + this.key + "::" + this.id;
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy