Package com.elasticinbox.core.cassandra.persistence

Source Code of com.elasticinbox.core.cassandra.persistence.AccountPersistence

/**
* Copyright (c) 2011-2012 Optimax Software Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*  * Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*  * Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*  * Neither the name of Optimax Software, ElasticInbox, nor the names
*    of its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package com.elasticinbox.core.cassandra.persistence;

import static me.prettyprint.hector.api.factory.HFactory.createColumn;
import static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;
import static com.elasticinbox.core.cassandra.CassandraDAOFactory.CF_ACCOUNTS;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import com.elasticinbox.common.utils.Assert;
import com.elasticinbox.core.IllegalLabelException;
import com.elasticinbox.core.cassandra.CassandraDAOFactory;
import com.elasticinbox.core.cassandra.utils.BatchConstants;
import com.elasticinbox.core.model.Label;
import com.elasticinbox.core.model.LabelMap;
import com.elasticinbox.core.model.ReservedLabels;

import me.prettyprint.cassandra.serializers.BytesArraySerializer;
import me.prettyprint.cassandra.serializers.SerializerTypeInferer;
import me.prettyprint.cassandra.serializers.StringSerializer;
import me.prettyprint.hector.api.beans.ColumnSlice;
import me.prettyprint.hector.api.beans.HColumn;
import me.prettyprint.hector.api.mutation.Mutator;
import me.prettyprint.hector.api.query.QueryResult;
import me.prettyprint.hector.api.query.SliceQuery;

public final class AccountPersistence
{
  private final static String CN_LABEL_NAME_PREFIX = "label";
  private final static String CN_LABEL_ATTRIBUTE_PREFIX = "lattr";
  private final static String CN_SEPARATOR = ":";

  private final static BytesArraySerializer byteSe = BytesArraySerializer.get();
  private final static StringSerializer strSe = StringSerializer.get();

  /**
   * Get all account attributes
   *
   * @param mailbox
   * @return
   * @throws IOException
   */
  public static Map<String, Object> getAll(final String mailbox)
  {
    // Create a query
    SliceQuery<String, String, byte[]> q =
        createSliceQuery(CassandraDAOFactory.getKeyspace(), strSe, strSe, byteSe);

    // set key, cf, range
    q.setColumnFamily(CF_ACCOUNTS).setKey(mailbox);
    q.setRange(null, null, false, BatchConstants.BATCH_READS); // TODO: make sure we get all columns
    // execute
    QueryResult<ColumnSlice<String, byte[]>> r = q.execute();

    // read attributes from the result
    Map<String, Object> attributes = new HashMap<String, Object>();
    for (HColumn<String, byte[]> c : r.get().getColumns()) {
      if( (c != null) && (c.getValue() != null)) {
        attributes.put(c.getName(), strSe.fromBytes(c.getValue()));
      }
    }

    return attributes;
  }

  /**
   * Add or update account attributes (columns)
   * 
   * @param account
   * @param attributes
   */
  public static <V> void set(Mutator<String> mutator, final String mailbox, final Map<String, V> attributes)
  {
    if (!attributes.isEmpty())
    {
      for (Map.Entry<String, V> a : attributes.entrySet())
      {
        mutator.addInsertion(mailbox, CF_ACCOUNTS,
            createColumn(a.getKey(), a.getValue(), strSe,
                SerializerTypeInferer.getSerializer(a.getValue())));
      }
    }
  }

  /**
   * Delete account
   *
   * @param mutator
   * @param mailbox
   */
  public static void delete(Mutator<String> mutator, final String mailbox)
  {
    mutator.addDeletion(mailbox, CF_ACCOUNTS, null, strSe);
  }

  /**
   * Get all labels
   *
   * @param mailbox
   * @return
   */
  public static LabelMap getLabels(final String mailbox)
  {
    LabelMap labels = new LabelMap();

    // get list of user specific labels from Cassandra
    Map<String, Object> attributes = getAll(mailbox);

    // add user specific labels
    for (Map.Entry<String, Object> a : attributes.entrySet())
    {
      if (a.getKey().startsWith(CN_LABEL_NAME_PREFIX))
      {
        // set label name
        Integer labelId = Integer.parseInt(a.getKey().split(CN_SEPARATOR)[1]);
        String labelName = (String) a.getValue();
       
        if (labels.containsId(labelId)) {
          labels.get(labelId).setName(labelName);
        } else {
          Label label = new Label(labelId, labelName);
          labels.put(label);
        }
      }
      else if (a.getKey().startsWith(CN_LABEL_ATTRIBUTE_PREFIX))
      {
        // set label custom attribute
        String[] attrKeys = a.getKey().split(CN_SEPARATOR);
        Integer labelId = Integer.parseInt(attrKeys[1]);
        String attrName = attrKeys[2];
        String attrValue = (String) a.getValue();
       
        if (labels.containsId(labelId)) {
          labels.get(labelId).addAttribute(attrName, attrValue);
        } else {
          Label label = new Label(labelId);
          label.addAttribute(attrName, attrValue);
          labels.put(label);
        }
      }
    }

    // add default reserved labels
    for (Label l : ReservedLabels.getAll())
    {
      Label label = new Label(l.getId(), l.getName());
      labels.put(label);
    }

    return labels;
  }

  /**
   * Inserts new or updates existing label.
   *
   * @param mutator
   * @param mailbox
   * @param label
   */
  public static void putLabel(Mutator<String> mutator, final String mailbox, Label label)
  {
    String labelKey = getLabelNameKey(label.getId());
    Map<String, String> attributes = new HashMap<String, String>(1);
   
    // upsert label name
    if (label.getName() != null)
    {
      attributes.put(labelKey, label.getName());
    }

    // upsert custom label attributes (delete if value is null or empty)
    if (label.getAttributes() != null)
    {
      for (Entry<String, String> labelAttr : label.getAttributes().entrySet())
      {
        // custom label attribute should not contain separator char
        if (labelAttr.getKey().contains(CN_SEPARATOR)) {
          throw new IllegalLabelException("Invalid character detected in the custom label attribute name.");
        }

        String labelAttrKey = getLabelAttributeKey(label.getId(), labelAttr.getKey());
       
        if (labelAttr.getValue() != null && !labelAttr.getValue().isEmpty()) {
          // upsert attribute
          attributes.put(labelAttrKey, labelAttr.getValue());
        } else {
          // delete if value is empty
          mutator.addDeletion(mailbox, CF_ACCOUNTS, labelAttrKey, strSe)
        }
      }
    }

    AccountPersistence.set(mutator, mailbox, attributes);
  }

  /**
   * Delete label from account
   *
   * @param mutator
   * @param mailbox
   * @param labelId
   */
  public static void deleteLabel(Mutator<String> mutator, final String mailbox, int labelId)
  {
    String labelNameKey = getLabelNameKey(labelId);
    String labelAttrPrefix = getLabelAttributeKey(labelId, ""); // label attributes prefix
   
    // delete label name
    mutator.addDeletion(mailbox, CF_ACCOUNTS, labelNameKey, strSe);

    // delete all attributes
    Map<String, Object> attributes = getAll(mailbox);
   
    for (String labelAttrKey : attributes.keySet())
    {
      if (labelAttrKey.startsWith(labelAttrPrefix))
      {
        mutator.addDeletion(mailbox, CF_ACCOUNTS, labelAttrKey, strSe);
      }
    }
  }

  /**
   * Generates key for custom label attribute.
   * <p>
   * Example <code>"lattr:123:MyAttribute"</code>
   *
   * @param labelId
   * @param attributeName Custom attribute name
   * @return
   */
  static String getLabelAttributeKey(int labelId, final String attributeName)
  {
    Assert.notNull(attributeName, "Attribute name cannot be null");
   
    return CN_LABEL_ATTRIBUTE_PREFIX +
          CN_SEPARATOR + labelId +
          CN_SEPARATOR + attributeName;
  }
 
  /**
   * Generates key for label name.
   * <p>
   * Example <code>"label:123"</code>
   *
   * @param labelId
   * @return
   */
  static String getLabelNameKey(int labelId)
  {
    return CN_LABEL_NAME_PREFIX + CN_SEPARATOR + labelId;
  }

}
TOP

Related Classes of com.elasticinbox.core.cassandra.persistence.AccountPersistence

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.