org.apache.usergrid.java.client.model.UsergridEntity.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.usergrid.java.client.model.UsergridEntity.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.usergrid.java.client.model;

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.node.*;
import org.apache.usergrid.java.client.UsergridEnums.*;
import org.apache.usergrid.java.client.Usergrid;
import org.apache.usergrid.java.client.UsergridClient;
import org.apache.usergrid.java.client.response.UsergridResponse;
import org.apache.usergrid.java.client.utils.JsonUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.util.*;

import static org.apache.usergrid.java.client.utils.JsonUtils.*;

@SuppressWarnings("unused")
public class UsergridEntity {

    @NotNull
    private static final HashMap<String, Class<? extends UsergridEntity>> subclassMappings = new HashMap<>();
    @NotNull
    private static final ObjectMapper entityUpdateMapper = new ObjectMapper();
    @NotNull
    private final ObjectReader entityUpdateReader = entityUpdateMapper.readerForUpdating(this);

    static {
        subclassMappings.put("user", UsergridUser.class);
        subclassMappings.put("device", UsergridDevice.class);
    }

    @NotNull
    private String type;
    @Nullable
    private String uuid;
    @Nullable
    private String name;
    @Nullable
    private Long created;
    @Nullable
    private Long modified;

    @NotNull
    private Map<String, JsonNode> properties = new HashMap<>();

    public UsergridEntity(@JsonProperty("type") @NotNull final String type) {
        this.type = type;
    }

    public UsergridEntity(@NotNull final String type, @Nullable final String name) {
        this(type);
        if (name != null) {
            this.name = name;
        }
    }

    public UsergridEntity(@NotNull final String type, @Nullable final String name,
            @NotNull final Map<String, ?> properties) {
        this(type, name);
        this.updatePropertiesWithMap(properties);
    }

    @Nullable
    public static Class<? extends UsergridEntity> customSubclassForType(@NotNull final String type) {
        return UsergridEntity.subclassMappings.get(type);
    }

    public void copyAllProperties(@NotNull final UsergridEntity fromEntity) {
        try {
            this.updatePropertiesWithJsonNode(entityUpdateMapper.valueToTree(fromEntity));
        } catch (IllegalArgumentException e) {
            System.out.print("Usergrid Error: Unable to update properties from entity - " + fromEntity.toString());
        }
    }

    public void updatePropertiesWithMap(@NotNull final Map<String, ?> properties) {
        try {
            this.updatePropertiesWithJsonNode(entityUpdateMapper.valueToTree(properties));
        } catch (IllegalArgumentException e) {
            System.out.print("Usergrid Error: Unable to update properties from map - " + properties.toString());
        }
    }

    public void updatePropertiesWithJsonNode(@NotNull final JsonNode node) {
        try {
            entityUpdateReader.readValue(node);
        } catch (IOException e) {
            System.out.print("Usergrid Error: Unable to update properties from jsonNode - " + node.toString());
        }
    }

    public static void mapCustomSubclassToType(@NotNull final String type,
            @NotNull final Class<? extends UsergridEntity> subclass) {
        UsergridEntity.subclassMappings.put(type, subclass);
    }

    @NotNull
    @Override
    public String toString() {
        return toJsonString(this);
    }

    @NotNull
    public String toPrettyString() {
        return toPrettyJsonString(this);
    }

    @NotNull
    public JsonNode toJsonObjectValue() {
        return toJsonNode(this);
    }

    @SuppressWarnings("unchecked")
    @NotNull
    public Map<String, ?> toMapValue() {
        return toMap(this);
    }

    @JsonIgnore
    public boolean isUser() {
        return (this instanceof UsergridUser || this.getType().equalsIgnoreCase(UsergridUser.USER_ENTITY_TYPE));
    }

    @NotNull
    public String getType() {
        return this.type;
    }

    private void setType(@NotNull final String type) {
        this.type = type;
    }

    @Nullable
    public String getUuid() {
        return this.uuid;
    }

    private void setUuid(@NotNull final String uuid) {
        this.uuid = uuid;
    }

    @Nullable
    public String getName() {
        return this.name;
    }

    protected void setName(@Nullable final String name) {
        this.name = name;
    }

    @Nullable
    public Long getCreated() {
        return this.created;
    }

    private void setCreated(@NotNull final Long created) {
        this.created = created;
    }

    @Nullable
    public Long getModified() {
        return this.modified;
    }

    private void setModified(@NotNull final Long modified) {
        this.modified = modified;
    }

    public void setLocation(final double latitude, final double longitude) {
        ObjectNode rootNode = JsonUtils.createObjectNode();
        rootNode.put("latitude", latitude);
        rootNode.put("longitude", longitude);
        setObjectProperty(this.properties, "location", rootNode);
    }

    @Nullable
    public String uuidOrName() {
        String uuidOrName = this.getUuid();
        if (uuidOrName == null) {
            uuidOrName = this.getName();
        }
        return uuidOrName;
    }

    @NotNull
    public UsergridResponse reload() {
        return this.reload(Usergrid.getInstance());
    }

    @NotNull
    public UsergridResponse reload(@NotNull final UsergridClient client) {
        String uuidOrName = this.uuidOrName();
        if (uuidOrName == null) {
            return UsergridResponse.fromError(client, "No UUID or name found.",
                    "The entity object must have a `uuid` or `name` assigned.");
        }
        UsergridResponse response = client.GET(this.getType(), uuidOrName);
        if (response.ok()) {
            UsergridEntity responseEntity = response.first();
            if (responseEntity != null) {
                this.copyAllProperties(responseEntity);
            }
        }
        return response;
    }

    @NotNull
    public UsergridResponse save() {
        return this.save(Usergrid.getInstance());
    }

    @NotNull
    public UsergridResponse save(@NotNull final UsergridClient client) {
        UsergridResponse response;
        if (this.getUuid() != null) {
            response = client.PUT(this);
        } else {
            response = client.POST(this);
        }
        if (response.ok()) {
            UsergridEntity responseEntity = response.first();
            if (responseEntity != null) {
                this.copyAllProperties(responseEntity);
            }
        }
        return response;
    }

    @NotNull
    public UsergridResponse remove() {
        return this.remove(Usergrid.getInstance());
    }

    @NotNull
    public UsergridResponse remove(@NotNull final UsergridClient client) {
        return client.DELETE(this);
    }

    @NotNull
    public UsergridResponse connect(@NotNull final String relationship, @NotNull final UsergridEntity toEntity) {
        return this.connect(Usergrid.getInstance(), relationship, toEntity);
    }

    @NotNull
    public UsergridResponse connect(@NotNull final UsergridClient client, @NotNull final String relationship,
            @NotNull final UsergridEntity toEntity) {
        return client.connect(this, relationship, toEntity);
    }

    @NotNull
    public UsergridResponse disconnect(@NotNull final String relationship,
            @NotNull final UsergridEntity fromEntity) {
        return this.disconnect(Usergrid.getInstance(), relationship, fromEntity);
    }

    @NotNull
    public UsergridResponse disconnect(@NotNull final UsergridClient client, @NotNull final String relationship,
            @NotNull final UsergridEntity fromEntity) {
        return client.disconnect(this, relationship, fromEntity);
    }

    @NotNull
    public UsergridResponse getConnections(@NotNull final UsergridDirection direction,
            @NotNull final String relationship) {
        return this.getConnections(Usergrid.getInstance(), direction, relationship);
    }

    @NotNull
    public UsergridResponse getConnections(@NotNull final UsergridClient client,
            @NotNull final UsergridDirection direction, @NotNull final String relationship) {
        return client.getConnections(direction, this, relationship);
    }

    public void removeProperty(@NotNull final String name) {
        putProperty(name, NullNode.getInstance());
    }

    public void removeProperties(@NotNull final List<String> names) {
        for (String propertyName : names) {
            this.removeProperty(propertyName);
        }
    }

    public void putProperty(@NotNull final String name, @NotNull final String value) {
        this.putProperty(name, JsonNodeFactory.instance.textNode(value));
    }

    public void putProperty(@NotNull final String name, final boolean value) {
        this.putProperty(name, JsonNodeFactory.instance.booleanNode(value));
    }

    public void putProperty(@NotNull final String name, @NotNull final List value) {
        this.putProperty(name, JsonNodeFactory.instance.pojoNode(value));
    }

    public void putProperty(@NotNull final String name, final int value) {
        this.putProperty(name, JsonNodeFactory.instance.numberNode(value));
    }

    public void putProperty(@NotNull final String name, final long value) {
        this.putProperty(name, JsonNodeFactory.instance.numberNode(value));
    }

    public void putProperty(@NotNull final String name, final float value) {
        this.putProperty(name, JsonNodeFactory.instance.numberNode(value));
    }

    public void putProperty(@NotNull final String name, @Nullable final JsonNode value) {
        UsergridEntityProperties entityProperty = UsergridEntityProperties.fromString(name);
        if (entityProperty != null && !entityProperty.isMutableForEntity(this)) {
            return;
        }

        JsonNode valueNode = value;
        if (valueNode == null) {
            valueNode = NullNode.getInstance();
        }
        this.updatePropertiesWithMap(Collections.singletonMap(name, valueNode));
    }

    public void putProperties(@NotNull final String jsonString) {
        try {
            JsonNode jsonNode = entityUpdateMapper.readTree(jsonString);
            this.putProperties(jsonNode);
        } catch (Exception ignore) {
        }
    }

    public void putProperties(@NotNull final Map<String, Object> properties) {
        try {
            JsonNode jsonNode = entityUpdateMapper.valueToTree(properties);
            this.putProperties(jsonNode);
        } catch (Exception ignore) {
        }
    }

    public void putProperties(@NotNull final JsonNode jsonNode) {
        HashMap<String, JsonNode> propertiesToUpdate = new HashMap<>();
        Iterator<Map.Entry<String, JsonNode>> keys = jsonNode.fields();
        while (keys.hasNext()) {
            Map.Entry<String, JsonNode> entry = keys.next();
            String key = entry.getKey();
            UsergridEntityProperties entityProperty = UsergridEntityProperties.fromString(key);
            if (entityProperty == null || entityProperty.isMutableForEntity(this)) {
                propertiesToUpdate.put(key, entry.getValue());
            }
        }
        if (!propertiesToUpdate.isEmpty()) {
            this.updatePropertiesWithMap(propertiesToUpdate);
        }
    }

    @SuppressWarnings("unchecked")
    public void append(@NotNull final String name, @NotNull final Object value) {
        this.append(name, (value instanceof List) ? (List<Object>) value : Collections.singletonList(value));
    }

    public void append(@NotNull final String name, @NotNull final List<Object> value) {
        this.insert(name, value, Integer.MAX_VALUE);
    }

    @SuppressWarnings("unchecked")
    public void insert(@NotNull final String name, @NotNull final Object value) {
        this.insert(name, (value instanceof List) ? (List<Object>) value : Collections.singletonList(value), 0);
    }

    @SuppressWarnings("unchecked")
    public void insert(@NotNull final String name, @NotNull final Object value, final int index) {
        this.insert(name, (value instanceof List) ? (List<Object>) value : Collections.singletonList(value), index);
    }

    public void insert(@NotNull final String name, @NotNull final List<Object> value) {
        this.insert(name, value, 0);
    }

    public void insert(@NotNull final String name, @NotNull final List<Object> value, final int index) {
        int indexToInsert = index;
        if (indexToInsert < 0) {
            indexToInsert = 0;
        }
        Object propertyValue = this.getEntityProperty(name);
        if (propertyValue != null) {
            ArrayList<Object> propertyArrayValue = this.convertToList(propertyValue);
            propertyArrayValue = this.insertIntoArray(propertyArrayValue, value, indexToInsert);
            this.putProperty(name, propertyArrayValue);
        } else {
            this.putProperty(name, value);
        }
    }

    public void pop(@NotNull final String name) {
        ArrayList<Object> arrayToPop = this.getArrayToPopOrShift(name);
        if (arrayToPop != null && !arrayToPop.isEmpty()) {
            arrayToPop.remove(arrayToPop.size() - 1);
            this.putProperty(name, arrayToPop);
        }
    }

    public void shift(@NotNull final String name) {
        ArrayList<Object> arrayToShift = this.getArrayToPopOrShift(name);
        if (arrayToShift != null && !arrayToShift.isEmpty()) {
            arrayToShift.remove(0);
            this.putProperty(name, arrayToShift);
        }
    }

    @Nullable
    public <T> T getEntityProperty(@NotNull final String name) {
        return JsonUtils.getProperty(this.properties, name);
    }

    @Nullable
    public JsonNode getJsonNodeProperty(@NotNull final String name) {
        return this.getProperties().get(name);
    }

    @Nullable
    public String getStringProperty(@NotNull final String name) {
        return JsonUtils.getStringProperty(this.getProperties(), name);
    }

    @Nullable
    public Boolean getBooleanProperty(@NotNull final String name) {
        Boolean booleanValue = null;
        Object object = JsonUtils.getProperty(this.getProperties(), name);
        if (object instanceof Boolean) {
            booleanValue = (Boolean) object;
        }
        return booleanValue;
    }

    @Nullable
    public Number getNumberProperty(@NotNull final String name) {
        Number numberValue = null;
        Object object = JsonUtils.getProperty(this.getProperties(), name);
        if (object instanceof Number) {
            numberValue = (Number) object;
        }
        return numberValue;
    }

    @Nullable
    public Integer getIntegerProperty(@NotNull final String name) {
        Integer integerValue = null;
        Object object = JsonUtils.getProperty(this.getProperties(), name);
        if (object instanceof Number) {
            integerValue = ((Number) object).intValue();
        }
        return integerValue;
    }

    @Nullable
    public Float getFloatProperty(@NotNull final String name) {
        Float floatValue = null;
        Object object = JsonUtils.getProperty(this.getProperties(), name);
        if (object instanceof Number) {
            floatValue = ((Number) object).floatValue();
        }
        return floatValue;
    }

    @Nullable
    public Long getLongProperty(@NotNull final String name) {
        Long longValue = null;
        Object object = JsonUtils.getProperty(this.getProperties(), name);
        if (object instanceof Number) {
            longValue = ((Number) object).longValue();
        }
        return longValue;
    }

    @JsonAnyGetter
    @NotNull
    public Map<String, JsonNode> getProperties() {
        return this.properties;
    }

    @JsonAnySetter
    private void internalPutProperty(@NotNull final String name, @Nullable final JsonNode value) {
        if (value == null) {
            properties.put(name, NullNode.instance);
        } else {
            properties.put(name, value);
        }
    }

    @Nullable
    @SuppressWarnings("unchecked")
    private ArrayList<Object> getArrayToPopOrShift(@NotNull final String name) {
        Object entityProperty = getEntityProperty(name);
        ArrayList<Object> arrayToPopOrShift = null;
        if (entityProperty instanceof POJONode) {
            Object objectValue = ((POJONode) entityProperty).getPojo();
            if (objectValue instanceof List) {
                arrayToPopOrShift = new ArrayList<>((List) objectValue);
            } else {
                arrayToPopOrShift = new ArrayList<>();
                arrayToPopOrShift.add(objectValue);
            }
        } else if (entityProperty instanceof ArrayNode) {
            arrayToPopOrShift = JsonUtils.convertToArrayList((ArrayNode) entityProperty);
        } else if (entityProperty instanceof List) {
            arrayToPopOrShift = new ArrayList<>((List) entityProperty);
        }
        return arrayToPopOrShift;
    }

    @NotNull
    private ArrayList<Object> convertToList(@NotNull final Object value) {
        ArrayList<Object> arrayList = new ArrayList<>();
        if (value instanceof ArrayNode) {
            arrayList = JsonUtils.convertToArrayList((ArrayNode) value);
        } else if (value instanceof POJONode) {
            Object objectValue = ((POJONode) value).getPojo();
            if (objectValue instanceof List) {
                arrayList.addAll((List) objectValue);
            } else {
                arrayList.add(objectValue);
            }
        } else if (value instanceof List) {
            arrayList.addAll((List) value);
        } else {
            arrayList.add(value);
        }
        return arrayList;
    }

    @NotNull
    private ArrayList<Object> insertIntoArray(@NotNull final List<Object> propertyArrayNode,
            @NotNull final List<Object> arrayToInsert, final int index) {
        ArrayList<Object> mergedArray = new ArrayList<>();
        if (propertyArrayNode.size() <= 0 || arrayToInsert.isEmpty()) {
            mergedArray.addAll(arrayToInsert);
        } else if (index <= 0) {
            mergedArray.addAll(arrayToInsert);
            mergedArray.addAll(propertyArrayNode);
        } else if (index > 0) {
            mergedArray.addAll(propertyArrayNode);
            if (index > propertyArrayNode.size()) {
                mergedArray.addAll(arrayToInsert);
            } else {
                mergedArray.addAll(index, arrayToInsert);
            }
        }
        return mergedArray;
    }
}