Package io.fathom.cloud.state

Source Code of io.fathom.cloud.state.ItemStates$ClassState

package io.fathom.cloud.state;

import io.fathom.cloud.Clock;
import io.fathom.cloud.CloudException;
import io.fathom.cloud.protobuf.ProtobufUtils;
import io.fathom.cloud.protobuf.CloudCommons.ItemStateData;

import java.util.Map;

import com.google.common.base.Optional;
import com.google.common.collect.Maps;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor.Type;
import com.google.protobuf.GeneratedMessage;
import com.google.protobuf.Message;
import com.google.protobuf.Message.Builder;

public class ItemStates {

    static class ClassState {
        final Descriptor descriptor;

        Optional<FieldDescriptor> itemStateField;

        public ClassState(Descriptor descriptor) {
            this.descriptor = descriptor;
        }

        public synchronized Optional<FieldDescriptor> getItemStateField() {
            if (itemStateField == null) {
                FieldDescriptor found = null;
                for (FieldDescriptor field : descriptor.getFields()) {
                    if (field.getType() != Type.MESSAGE) {
                        continue;
                    }

                    if (field.getMessageType().equals(ItemStateData.getDescriptor())) {
                        if (found != null) {
                            throw new IllegalStateException();
                        }
                        found = field;
                    }
                }
                itemStateField = Optional.fromNullable(found);
            }

            return itemStateField;
        }
    }

    static final Map<Descriptor, ClassState> classes = Maps.newHashMap();

    public static <T extends GeneratedMessage> boolean isDeleted(T msg) {
        ItemStateData itemState = getItemState(msg);
        if (itemState == null) {
            return false;
        }
        return itemState.hasDeletedAt();
    }

    public static <T extends GeneratedMessage> ItemStateData getItemState(T msg) {
        FieldDescriptor field = findItemStateField(msg.getDescriptorForType());
        if (field == null) {
            return null;
        }
        try {
            return (ItemStateData) msg.getField(field);
        } catch (Exception e) {
            throw new IllegalArgumentException("Error reading item state field", e);
        }
    }

    private static FieldDescriptor findItemStateField(Descriptor descriptorForType) {
        return getClassState(descriptorForType).getItemStateField().orNull();
    }

    private static ClassState getClassState(Descriptor descriptor) {
        synchronized (classes) {
            ClassState classState = classes.get(descriptor);
            if (classState == null) {
                classState = new ClassState(descriptor);
                classes.put(descriptor, classState);
            }
            return classState;
        }
    }

    public static <T extends GeneratedMessage> T markDeleted(NumberedItemCollection<T> store, T msg)
            throws CloudException {
        Message.Builder builder = ProtobufUtils.newBuilder(msg.getClass());
        builder.mergeFrom(msg);

        FieldDescriptor field = findItemStateField(msg.getDescriptorForType());
        if (field == null) {
            throw new IllegalStateException();
        }

        ItemStateData itemStateData;
        try {
            itemStateData = (ItemStateData) builder.getField(field);
        } catch (Exception e) {
            throw new IllegalArgumentException("Error reading item state field", e);
        }

        if (itemStateData.hasDeletedAt()) {
            throw new IllegalStateException();
        }

        ItemStateData.Builder b = ItemStateData.newBuilder(itemStateData);
        b.setDeletedAt(Clock.getTimestamp());
        builder.setField(field, b.build());

        return store.update(builder);
    }

    public static boolean usesItemState(Descriptor descriptor) {
        return getClassState(descriptor).getItemStateField().isPresent();
    }

    public static void setUpdatedAt(Builder item) {
        Descriptor descriptor = item.getDescriptorForType();
        Optional<FieldDescriptor> itemStateField = getClassState(descriptor).getItemStateField();
        if (itemStateField.isPresent()) {
            ItemStateData itemStateData;
            try {
                itemStateData = (ItemStateData) item.getField(itemStateField.get());
            } catch (Exception e) {
                throw new IllegalArgumentException("Error reading item state field", e);
            }

            ItemStateData.Builder b = ItemStateData.newBuilder(itemStateData);
            b.setUpdatedAt(Clock.getTimestamp());
            item.setField(itemStateField.get(), b.build());
        }
    }

    public static void setCreatedAt(Builder item) {
        Descriptor descriptor = item.getDescriptorForType();
        Optional<FieldDescriptor> itemStateField = getClassState(descriptor).getItemStateField();
        if (itemStateField.isPresent()) {
            ItemStateData itemStateData;
            try {
                itemStateData = (ItemStateData) item.getField(itemStateField.get());
            } catch (Exception e) {
                throw new IllegalArgumentException("Error reading item state field", e);
            }

            ItemStateData.Builder b = ItemStateData.newBuilder(itemStateData);
            b.setCreatedAt(Clock.getTimestamp());
            item.setField(itemStateField.get(), b.build());
        }
    }

}
TOP

Related Classes of io.fathom.cloud.state.ItemStates$ClassState

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.