blob: a4f59b1020be917467a9a318cc99642fa3ebf6dd [file] [log] [blame]
/*
* Copyright (c) 2011, 2021 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
*/
package org.eclipse.persistence.jpa.rs.util.xmladapters;
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.FetchGroupManager;
import org.eclipse.persistence.internal.jpa.rs.metadata.model.Link;
import org.eclipse.persistence.internal.jpa.rs.weaving.PersistenceWeavedRest;
import org.eclipse.persistence.jpa.JpaHelper;
import org.eclipse.persistence.jpa.rs.PersistenceContext;
import org.eclipse.persistence.jpa.rs.ReservedWords;
import org.eclipse.persistence.jpa.rs.exceptions.JPARSException;
import org.eclipse.persistence.jpa.rs.util.IdHelper;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.mappings.XMLInverseReferenceMapping;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.queries.FetchGroupTracker;
public class ReferenceAdapter<T extends PersistenceWeavedRest> extends XmlAdapter<Object, Object> {
private String baseURI = null;
private PersistenceContext context = null;
/**
* Instantiates a new reference adapter.
*/
public ReferenceAdapter() {
super();
}
/**
* Instantiates a new reference adapter.
*
* @param baseURI
* the base uri
* @param context
* the context
*/
public ReferenceAdapter(String baseURI, PersistenceContext context) {
this.baseURI = baseURI;
this.context = context;
}
/*
* (non-Javadoc)
*
* @see
* jakarta.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public Link marshal(Object o) throws Exception {
if (o == null) {
return null;
}
ClassDescriptor descriptor = context.getJAXBDescriptorForClass(o.getClass());
T t = (T) descriptor.getObjectBuilder().buildNewInstance();
Link link = new Link();
link.setMethod("GET");
link.setRel(ReservedWords.JPARS_REL_SELF);
String id = IdHelper.stringifyId(o, descriptor.getAlias(), context);
String version = context.getVersion();
if (version != null) {
link.setHref(baseURI + version + "/" + context.getName() + "/entity/" + descriptor.getAlias() + "/" + id);
} else {
link.setHref(baseURI + context.getName() + "/entity/" + descriptor.getAlias() + "/" + id);
}
descriptor.getMappingForAttributeName("_persistence_href").setAttributeValueInObject(t, link);
return link;
}
/*
* (non-Javadoc)
*
* @see
* jakarta.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public T unmarshal(Object object) throws Exception {
if (object == null) {
return null;
}
PersistenceWeavedRest persistenceWeavedRest = null;
Link link;
if (object instanceof PersistenceWeavedRest) {
persistenceWeavedRest = (PersistenceWeavedRest) object;
link = persistenceWeavedRest._persistence_getHref();
} else if (object instanceof Link) {
link = (Link) object;
} else {
return null;
}
if (null == link || link.getHref() == null) {
if (persistenceWeavedRest != null) {
ClassDescriptor descriptor = context.getJAXBDescriptorForClass(persistenceWeavedRest.getClass());
if (persistenceWeavedRest instanceof FetchGroupTracker && JpaHelper.getDatabaseSession(context.getEmf()).doesObjectExist(persistenceWeavedRest)) {
if (context.doesExist(null, persistenceWeavedRest)) {
FetchGroup fetchGroup = new FetchGroup();
for (DatabaseMapping mapping : descriptor.getMappings()) {
if (!(mapping instanceof XMLInverseReferenceMapping)) {
fetchGroup.addAttribute(mapping.getAttributeName());
}
}
(new FetchGroupManager()).setObjectFetchGroup(persistenceWeavedRest, fetchGroup, null);
}
}
return (T) persistenceWeavedRest;
}
}
// Construct object from the href
if ((link != null) && (link.getHref() != null)) {
String uri = link.getHref().replace("\\/", "/");
String entityType = uri.substring(uri.indexOf("/entity/"), uri.lastIndexOf('/'));
entityType = entityType.substring(entityType.lastIndexOf('/') + 1);
String entityId = uri.substring(uri.lastIndexOf('/') + 1);
ClassDescriptor descriptor = context.getDescriptor(entityType);
Object id = IdHelper.buildId(context, descriptor.getAlias(), entityId);
T foundEntity = (T) getObjectById(entityType, id);
return foundEntity;
}
return null;
}
private Object getObjectById(String entityType, Object id) throws Exception {
Object entity = context.find(null, entityType, id, null);
if (entity != null) {
return entity;
}
// It is an error if the object referred by a link doesn't exist, so throw exception
throw JPARSException.objectReferredByLinkDoesNotExist(entityType, id);
}
}