Java tutorial
/* * 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.android.sdk.entities; import static org.apache.usergrid.android.sdk.utils.JsonUtils.getUUIDProperty; import static org.apache.usergrid.android.sdk.utils.JsonUtils.setBooleanProperty; import static org.apache.usergrid.android.sdk.utils.JsonUtils.setFloatProperty; import static org.apache.usergrid.android.sdk.utils.JsonUtils.setLongProperty; import static org.apache.usergrid.android.sdk.utils.JsonUtils.setStringProperty; import static org.apache.usergrid.android.sdk.utils.JsonUtils.setUUIDProperty; import static org.apache.usergrid.android.sdk.utils.JsonUtils.toJsonString; import static org.apache.usergrid.android.sdk.utils.MapUtils.newMapWithoutKeys; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import org.apache.usergrid.android.sdk.UGClient; import org.apache.usergrid.android.sdk.UGClient.Query; import org.apache.usergrid.android.sdk.response.ApiResponse; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; /** * Models an entity of any type as a local object. Type-specific * classes are extended from this class. * * @see <a href="http://apigee.com/docs/app-services/content/app-services-data-model-1">Usergrid data model documentation</a> */ public class Entity { public final static String PROPERTY_UUID = "uuid"; public final static String PROPERTY_TYPE = "type"; public final static String PROPERTY_NAME = "name"; public final static String PROPERTY_METADATA = "metadata"; public final static String PROPERTY_CREATED = "created"; public final static String PROPERTY_MODIFIED = "modified"; public final static String PROPERTY_ACTIVATED = "activated"; protected Map<String, JsonNode> properties = new HashMap<String, JsonNode>(); private UGClient client; public static Map<String, Class<? extends Entity>> CLASS_FOR_ENTITY_TYPE = new HashMap<String, Class<? extends Entity>>(); static { CLASS_FOR_ENTITY_TYPE.put(User.ENTITY_TYPE, User.class); } /** * Default constructor for instantiating an Entity object. */ public Entity() { } /** * Constructor for instantiating an Entity with a UGClient. * @param UGClient a UGClient object */ public Entity(UGClient client) { this.client = client; } /** * Constructor for instantiating an Entity with a UGClient * and entity type. Normally this is the constructor that should * be used to model an entity locally. * @param UGClient a UGClient object * @param type the 'type' property of the entity */ public Entity(UGClient client, String type) { this.client = client; setType(type); } /** * Gets the UGClient currently saved in the Entity object. * @return the UGClient instance */ public UGClient getUGClient() { return client; } /** * Sets the UGClient in the Entity object. * @param UGClient the UGClient instance */ public void setUGClient(UGClient client) { this.client = client; } /** * Gets the 'type' of the Entity object. * @return the 'type' of the entity */ @JsonIgnore public String getNativeType() { return getType(); } /** * Adds the type and UUID properties to the Entity object, then * returns all object properties. * @return a List object with the entity UUID and type */ @JsonIgnore public List<String> getPropertyNames() { List<String> properties = new ArrayList<String>(); properties.add(PROPERTY_TYPE); properties.add(PROPERTY_UUID); return properties; } /** * Gets the String value of the specified Entity property. * @param name the name of the property * @return the property value. Returns null if the property has no value */ public String getStringProperty(String name) { JsonNode val = this.properties.get(name); return val != null ? val.textValue() : null; } /** * Gets the boolean value of the specified Entity property. * @param name the name of the property * @return the property value */ public boolean getBoolProperty(String name) { return this.properties.get(name).booleanValue(); } /** * Gets the Int value of the specified Entity property. * @param name the name of the property * @return the property value */ public int getIntProperty(String name) { return this.properties.get(name).intValue(); } /** * Gets the Double value of the specified Entity property. * @param name the name of the property * @return the property value */ public double getDoubleProperty(String name) { return this.properties.get(name).doubleValue(); } /** * Gets the long value of the specified Entity property. * @param name the name of the property * @return the property value */ public long getLongProperty(String name) { return this.properties.get(name).longValue(); } /** * Gets the 'type' property of the Entity object. * @return the Entity type */ public String getType() { return getStringProperty(PROPERTY_TYPE); } /** * Sets the 'type' property of the Entity object. * @param type the entity type */ public void setType(String type) { setStringProperty(properties, PROPERTY_TYPE, type); } /** * Gets the 'uuid' property of the Entity object. * @return the Entity UUID */ public UUID getUuid() { return getUUIDProperty(properties, PROPERTY_UUID); } /** * Sets the 'uuid' property of the Entity object. * @param uuid the entity UUID */ public void setUuid(UUID uuid) { setUUIDProperty(properties, PROPERTY_UUID, uuid); } /** * Returns a HashMap of the Entity properties without keys. * * @return a HashMap object with no keys and the value of the Entity properties */ @JsonAnyGetter public Map<String, JsonNode> getProperties() { return newMapWithoutKeys(properties, getPropertyNames()); } /** * Adds a property to the Entity object. * * @param name the name of the property to be set * @param value the value of the property as a JsonNode object. * If the value is null, the property will be removed from the object. * @see <a href="http://jackson.codehaus.org/1.0.1/javadoc/org/codehaus/jackson/JsonNode.html">JsonNode</a> */ @JsonAnySetter public void setProperty(String name, JsonNode value) { if (value == null) { properties.remove(name); } else { properties.put(name, value); } } /** * Removes all properties from the Entity object, then adds multiple properties. * * @param newProperties a Map object that contains the * property names as keys and their values as values. * Property values must be JsonNode objects. If the value * is null, the property will be removed from the object. * @see <a href="http://jackson.codehaus.org/1.0.1/javadoc/org/codehaus/jackson/JsonNode.html">JsonNode</a> */ public void setProperties(Map<String, JsonNode> newProperties) { properties.clear(); Set<String> keySet = newProperties.keySet(); Iterator<String> keySetIter = keySet.iterator(); while (keySetIter.hasNext()) { String key = keySetIter.next(); setProperty(key, newProperties.get(key)); } } /** * Adds a property to the Entity object with a String value. * * @param name the name of the property to be set * @param value the String value of the property */ public void setProperty(String name, String value) { setStringProperty(properties, name, value); } /** * Adds a property to the Entity object with a boolean value. * * @param name the name of the property to be set * @param value the boolean value of the property */ public void setProperty(String name, boolean value) { setBooleanProperty(properties, name, value); } /** * Adds a property to the Entity object with a long value. * * @param name the name of the property to be set * @param value the long value of the property */ public void setProperty(String name, long value) { setLongProperty(properties, name, value); } /** * Adds a property to the Entity object with a int value. * * @param name the name of the property to be set * @param value the int value of the property */ public void setProperty(String name, int value) { setProperty(name, (long) value); } /** * Adds a property to the Entity object with a float value. * * @param name the name of the property to be set * @param value the float value of the property */ public void setProperty(String name, float value) { setFloatProperty(properties, name, value); } /** * Returns the Entity object as a JSON-formatted string */ @Override public String toString() { return toJsonString(this); } /** * @y.exclude */ public <T extends Entity> T toType(Class<T> t) { return toType(this, t); } /** * @y.exclude */ public static <T extends Entity> T toType(Entity entity, Class<T> t) { if (entity == null) { return null; } T newEntity = null; if (entity.getClass().isAssignableFrom(t)) { try { newEntity = (t.newInstance()); if ((newEntity.getNativeType() != null) && newEntity.getNativeType().equals(entity.getType())) { newEntity.properties = entity.properties; } } catch (Exception e) { e.printStackTrace(); } } return newEntity; } /** * @y.exclude */ public static <T extends Entity> List<T> toType(List<Entity> entities, Class<T> t) { List<T> l = new ArrayList<T>(entities != null ? entities.size() : 0); if (entities != null) { for (Entity entity : entities) { T newEntity = entity.toType(t); if (newEntity != null) { l.add(newEntity); } } } return l; } /** * Fetches the current state of the entity from the server and saves * it in the Entity object. Runs synchronously. * * @return an ApiResponse object */ public ApiResponse fetch() { ApiResponse response = new ApiResponse(); String type = this.getType(); UUID uuid = this.getUuid(); // may be NULL String entityId = null; if (uuid != null) { entityId = uuid.toString(); } else { if (User.isSameType(type)) { String username = this.getStringProperty(User.PROPERTY_USERNAME); if ((username != null) && (username.length() > 0)) { entityId = username; } else { String error = "no_username_specified"; this.client.writeLog(error); response.setError(error); //response.setErrorCode(error); return response; } } else { String name = this.getStringProperty(PROPERTY_NAME); if ((name != null) && (name.length() > 0)) { entityId = name; } else { String error = "no_name_specified"; this.client.writeLog(error); response.setError(error); //response.setErrorCode(error); return response; } } } Query q = this.client.queryEntitiesRequest("GET", null, null, this.client.getOrganizationId(), this.client.getApplicationId(), type, entityId); response = q.getResponse(); if (response.getError() != null) { this.client.writeLog("Could not get entity."); } else { if (response.getUser() != null) { this.addProperties(response.getUser().getProperties()); } else if (response.getEntityCount() > 0) { Entity entity = response.getFirstEntity(); this.setProperties(entity.getProperties()); } } return response; } /** * Saves the Entity object as an entity on the server. Any * conflicting properties on the server will be overwritten. Runs synchronously. * * @return an ApiResponse object */ public ApiResponse save() { ApiResponse response = null; UUID uuid = this.getUuid(); boolean entityAlreadyExists = false; if (client.isUuidValid(uuid)) { entityAlreadyExists = true; } // copy over all properties except some specific ones Map<String, Object> data = new HashMap<String, Object>(); Set<String> keySet = this.properties.keySet(); Iterator<String> keySetIter = keySet.iterator(); while (keySetIter.hasNext()) { String key = keySetIter.next(); if (!key.equals(PROPERTY_METADATA) && !key.equals(PROPERTY_CREATED) && !key.equals(PROPERTY_MODIFIED) && !key.equals(PROPERTY_ACTIVATED) && !key.equals(PROPERTY_UUID)) { data.put(key, this.properties.get(key)); } } if (entityAlreadyExists) { // update it response = this.client.updateEntity(uuid.toString(), data); } else { // create it response = this.client.createEntity(data); } if (response.getError() != null) { this.client.writeLog("Could not save entity."); } else { if (response.getEntityCount() > 0) { Entity entity = response.getFirstEntity(); this.setProperties(entity.getProperties()); } } return response; } /** * Deletes the entity on the server. * * @return an ApiResponse object */ public ApiResponse destroy() { ApiResponse response = new ApiResponse(); String type = getType(); String uuidAsString = null; UUID uuid = getUuid(); if (uuid != null) { uuidAsString = uuid.toString(); } else { String error = "Error trying to delete object: No UUID specified."; this.client.writeLog(error); response.setError(error); //response.setErrorCode(error); return response; } response = this.client.removeEntity(type, uuidAsString); if ((response != null) && (response.getError() != null)) { this.client.writeLog("Entity could not be deleted."); } else { this.properties.clear(); } return response; } /** * Adds multiple properties to the Entity object. Pre-existing properties will * be preserved, unless there is a conflict, then the pre-existing property * will be overwritten. * * @param properties a Map object that contains the * property names as keys and their values as values. * Property values must be JsonNode objects. If the value * is null, the property will be removed from the object. * @see <a href="http://jackson.codehaus.org/1.0.1/javadoc/org/codehaus/jackson/JsonNode.html">JsonNode</a> */ public void addProperties(Map<String, JsonNode> properties) { Set<String> keySet = properties.keySet(); Iterator<String> keySetIter = keySet.iterator(); while (keySetIter.hasNext()) { String key = keySetIter.next(); setProperty(key, properties.get(key)); } } /** * Creates a connection between two entities. * * @param connectType the type of connection * @param targetEntity the UUID of the entity to connect to * @return an ApiResponse object */ public ApiResponse connect(String connectType, Entity targetEntity) { return this.client.connectEntities(this.getType(), this.getUuid().toString(), connectType, targetEntity.getUuid().toString()); } /** * Destroys a connection between two entities. * * @param connectType the type of connection * @param targetEntity the UUID of the entity to disconnect from * @return an ApiResponse object */ public ApiResponse disconnect(String connectType, Entity targetEntity) { return this.client.disconnectEntities(this.getType(), this.getUuid().toString(), connectType, targetEntity.getUuid().toString()); } }