| /* |
| * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // bdoughan - initial implementation |
| // tware - initial unmarshall method |
| package org.eclipse.persistence.jpa.rs.util.xmladapters; |
| |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import jakarta.xml.bind.annotation.adapters.XmlAdapter; |
| |
| import org.eclipse.persistence.config.CacheUsage; |
| import org.eclipse.persistence.config.QueryHints; |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.internal.dynamic.DynamicEntityImpl; |
| import org.eclipse.persistence.jpa.rs.PersistenceContext; |
| import org.eclipse.persistence.jpa.rs.util.IdHelper; |
| import org.eclipse.persistence.mappings.DatabaseMapping; |
| import org.eclipse.persistence.queries.FetchGroup; |
| |
| /** |
| * Used with JAXB to convert from a URL representing an relationship to an object |
| * It provides functionality at marshall and unmarshall time |
| * |
| * At marshall time, the target of a relationship will be marshalled as a URL that could be |
| * used to find the object through a REST service |
| * |
| * At unmarsall time, the URL will be deconstructed and used to find the object in JPA. |
| * |
| * @author tware |
| * |
| */ |
| public class LinkAdapter extends XmlAdapter<String, Object> { |
| |
| private String baseURI = null; |
| protected PersistenceContext context; |
| |
| public LinkAdapter() { |
| } |
| |
| public LinkAdapter(String baseURI, PersistenceContext context) { |
| this.baseURI = baseURI; |
| this.context = context; |
| } |
| |
| @Override |
| public Object unmarshal(String v) throws Exception { |
| if (v.equals("")){ |
| return null; |
| } |
| String fixedString = v.replace("\\/", "/"); |
| int lastSlash = fixedString.lastIndexOf('/'); |
| String entityType = fixedString.substring((baseURI + context.getName() + "/entity/" ).length(), lastSlash); |
| String entityId = fixedString.substring(lastSlash + 1); |
| ClassDescriptor descriptor = context.getDescriptor(entityType); |
| Object id = IdHelper.buildId(context, descriptor.getAlias(), entityId); |
| |
| return constructObjectForId(entityType, id); |
| } |
| |
| protected Object constructObjectForId(String entityType, Object id){ |
| |
| FetchGroup fetchGroup = new FetchGroup(); |
| ClassDescriptor descriptor = context.getDescriptor(entityType); |
| List<DatabaseMapping> pkMappings = descriptor.getObjectBuilder().getPrimaryKeyMappings(); |
| for (DatabaseMapping mapping: pkMappings){ |
| fetchGroup.addAttribute(mapping.getAttributeName()); |
| } |
| Map<String, Object> properties = new HashMap<String, Object>(); |
| properties.put(QueryHints.FETCH_GROUP, fetchGroup); |
| properties.put(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly); |
| Object entity = context.find(null, entityType, id, properties); |
| |
| if (entity == null){ |
| return IdHelper.buildObjectShell(context, entityType, id); |
| } |
| return entity; |
| } |
| |
| @Override |
| public String marshal(Object v) throws Exception { |
| if (null == v) { |
| return null; |
| } |
| |
| String href = null; |
| String version = context.getVersion(); |
| |
| if (version != null) { |
| href = baseURI + version + "/" + context.getName() + "/entity/" + v.getClass().getSimpleName() + "/" |
| + IdHelper.stringifyId(v, ((DynamicEntityImpl) v).getType().getName(), context); |
| } else { |
| href = baseURI + context.getName() + "/entity/" + v.getClass().getSimpleName() + "/" |
| + IdHelper.stringifyId(v, ((DynamicEntityImpl) v).getType().getName(), context); |
| } |
| return href; |
| } |
| } |