/* * Copyright (C) 2015 Red Hat, Inc. and/or its affiliates. * * 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 org.jboss.errai.jpa.client.local; import org.jboss.errai.common.client.api.Assert; import com.google.gwt.json.client.JSONException; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONString; import com.google.gwt.json.client.JSONValue; /** * Holder class for a storage key: a tuple of type and identity value. * <p> * Instances of this class are immutable. * * @param <X> The entity's Java type * @param <T> The entity's identity type * @author Jonathan Fuerth <jfuerth@gmail.com> */ public class Key<X, T> { private final ErraiManagedType<X> entityType; private final T id; /** * Creates a key that uniquely identifies an entity of a particular type (the * entity with this identity does not necessarily exist, but if it did, this * would be its identity). * * @param entityType The type of the entity. Must not be null. * @param id The ID of the entity. Must not be null. * @throws NullPointerException if either argument is null. */ public Key(ErraiManagedType<X> entityType, T id) { this.entityType = Assert.notNull(entityType); this.id = Assert.notNull(id); } /** * Returns a Key instance for the entity type of the given class. * * @param em * The entity manager (required for looking up the EntityType for the * given class). Must not be null. * @param entityClass * The class of the entity for the key. Must not be null. * @param id * The ID value for the entity. Must not be null. * @return A Key instance for the given entity type and ID value. * @throws NullPointerException * if any argument is null. * @throws IllegalArgumentException * if {@code entityClass} is not a known JPA entity type. */ public static <X, T> Key<X, T> get(ErraiEntityManager em, Class<X> entityClass, T id) { ErraiIdentifiableType<X> entityType = em.getMetamodel().entity(entityClass); return new Key<X, T>(entityType, id); } /** * Returns the managed type this key refers to. * * @return the entity type of the key. Never null. */ public ErraiManagedType<X> getEntityType() { return entityType; } /** * Returns the ID value for this key. * * @return the ID value of the key. Never null. */ public T getId() { return id; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((entityType == null) ? 0 : entityType.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Key<?, ?> other = (Key<?, ?>) obj; if (entityType == null) { if (other.entityType != null) return false; } else if (!entityType.equals(other.entityType)) return false; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } @Override public String toString() { return "Key [entityType=" + entityType + ", id=" + id + "]"; } /** * Returns a JSON string representation of this key which can be turned back * into a Key instance via * {@link Key#fromJson(ErraiEntityManager, String, boolean)}. * * @see #toJsonObject() * @return a JSON-formatted string. Never null. */ public String toJson() { return toJsonObject().toString(); } /** * Returns a JSONObject representation of this key which can be turned back * into a Key instance via * {@link Key#fromJsonObject(ErraiEntityManager, JSONObject, boolean)}. * * @see #toJson() * @return a JSON object that represents this key. Never null. */ public JSONObject toJsonObject() { JSONObject keyJson = new JSONObject(); keyJson.put("entityType", new JSONString(entityType.getJavaType().getName())); keyJson.put("id", JsonUtil.basicValueToJson(id)); return keyJson; } /** * Returns a Key instance based on the given JSON string. * * @param em * The entity manager that can be used to look up the entity type * corresponding with the key. * @param key * The key to parse. * @param failIfNotFound * If true, and the entity type given in {@code key} is not known to * {@code em}, an IllegalArgumentException will be thrown. * @return An instance of Key that corresponds with the entity type and ID of * the given JSON string. */ public static Key<?, ?> fromJson(ErraiEntityManager em, String key, boolean failIfNotFound) { JSONValue k; try { k = JSONParser.parseStrict(key); } catch (JSONException e) { throw new JSONException("Input: " + key, e); } return fromJsonObject(em, k.isObject(), failIfNotFound); } /** * Returns a Key instance based on the given JSON object. * * @param em * The entity manager that can be used to look up the entity type * corresponding with the key. * @param key * The properties of the key to create. * @param failIfNotFound * If true, and the entity type given in {@code key} is not known to * {@code em}, an IllegalArgumentException will be thrown. * @return An instance of Key that corresponds with the entity type and ID of * the given JSON object. */ public static Key<?, ?> fromJsonObject(ErraiEntityManager em, JSONObject key, boolean failIfNotFound) { String entityClassName = key.get("entityType").isString().stringValue(); ErraiIdentifiableType<Object> et = em.getMetamodel().entity(entityClassName, failIfNotFound); if (et == null) { return null; } ErraiSingularAttribute<?, Object> idAttr = et.getId(Object.class); Object id = JsonUtil.basicValueFromJson(key.get("id"), idAttr.getJavaType()); return new Key<Object, Object>(et, id); } }