org.eclipse.persistence.jpa.rs.util.xmladapters.ReferenceAdapterV2 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction 774c696
/*******************************************************************************
* Copyright (c) 2014 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Dmitry Kornilov - Initial implementation
******************************************************************************/
package org.eclipse.persistence.jpa.rs.util.xmladapters;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.jpa.rs.metadata.model.ItemLinks;
import org.eclipse.persistence.internal.jpa.rs.metadata.model.LinkV2;
import org.eclipse.persistence.internal.weaving.PersistenceWeavedRest;
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.features.ItemLinksBuilder;
import org.eclipse.persistence.jpa.rs.util.HrefHelper;
import org.eclipse.persistence.jpa.rs.util.IdHelper;
import javax.xml.bind.annotation.adapters.XmlAdapter;
/**
* Reference adapter used in JPARS V2. Main purpose of this adapter is retrieving an entity
* by link when unmarshalling.
*
* @param entity class of this adapter
*
* @author Dmitry Kornilov
* @since EclipseLink 2.6.0
*/
public class ReferenceAdapterV2 extends XmlAdapter {
protected PersistenceContext context;
public ReferenceAdapterV2() {
super();
}
/**
* Instantiates a new reference adapter.
*
* @param context persistent context (mandatory)
*/
public ReferenceAdapterV2(PersistenceContext context) {
this.context = context;
}
/**
* Marshal just passes through.
*
* @param o
* @return
* @throws Exception
*/
@Override
public T marshal(T o) throws Exception {
if (o == null) {
return null;
}
// Add canonical link
final String href = HrefHelper.buildEntityHref(context, o.getClass().getSimpleName(), IdHelper.stringifyId(o, o.getClass().getSimpleName(), context));
if (o._persistence_getLinks() == null) {
final ItemLinks itemLinks = (new ItemLinksBuilder()).addCanonical(href).build();
o._persistence_setLinks(itemLinks);
} else {
final ItemLinks itemLinks = o._persistence_getLinks();
final LinkV2 canonicalLink = itemLinks.getCanonicalLink();
if (canonicalLink == null) {
o._persistence_getLinks().addLink(new LinkV2(ReservedWords.JPARS_REL_CANONICAL, href));
}
}
return o;
}
/**
* If 'canonical' or 'self' link is present loads entity from the database. Otherwise uses data provided.
*/
@Override
public T unmarshal(T o) throws Exception {
if (o == null) {
return null;
}
if (context == null) {
return o;
}
// Check if links exist and load entity if it does
if (o._persistence_getLinks() != null && o._persistence_getLinks().getLinks() != null && !o._persistence_getLinks().getLinks().isEmpty()) {
final ItemLinks itemLinks = o._persistence_getLinks();
// Use canonical link
final LinkV2 canonicalLink = itemLinks.getCanonicalLink();
if (canonicalLink != null && canonicalLink.getHref() != null) {
return loadEntity(canonicalLink.getHref()) ;
}
// Use self link if canonical is not found
final LinkV2 selfLink = itemLinks.getSelfLink();
if (selfLink != null && selfLink.getHref() != null) {
return loadEntity(selfLink.getHref()) ;
}
}
return o;
}
private T loadEntity(String href) throws Exception {
final String uri = href.replace("\\/", "/");
String entityType = uri.substring(uri.indexOf("/entity/"), uri.lastIndexOf('/'));
entityType = entityType.substring(entityType.lastIndexOf("/") + 1);
final String entityId = uri.substring(uri.lastIndexOf("/") + 1);
final ClassDescriptor descriptor = context.getDescriptor(entityType);
final Object id = IdHelper.buildId(context, descriptor.getAlias(), entityId);
return getObjectById(entityType, id);
}
private T getObjectById(String entityType, Object id) throws Exception {
final Object entity = context.find(null, entityType, id, null);
if (entity != null) {
return (T)entity;
}
// It is an error if the object referred by a link doesn't exist, so throw exception
throw JPARSException.objectReferredByLinkDoesNotExist(entityType, id);
}
}