11/*
22 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
33 *
4- * Copyright (c) 2010-2016 Oracle and/or its affiliates. All rights reserved.
4+ * Copyright (c) 2010-2017 Oracle and/or its affiliates. All rights reserved.
55 *
66 * The contents of this file are subject to the terms of either the GNU
77 * General Public License Version 2 only ("GPL") or the Common Development
4343import java .lang .reflect .Modifier ;
4444import java .net .URI ;
4545import java .util .ArrayList ;
46- import java .util .logging .Level ;
47- import java .util .logging .Logger ;
4846import java .util .HashSet ;
4947import java .util .List ;
5048import java .util .Map ;
5149import java .util .Set ;
50+ import java .util .logging .Level ;
51+ import java .util .logging .Logger ;
52+
5253import javax .ws .rs .core .Link ;
5354import javax .ws .rs .core .UriInfo ;
55+
5456import javax .xml .bind .annotation .XmlTransient ;
5557
58+ import org .glassfish .jersey .linking .contributing .ResourceLinkContributionContext ;
5659import org .glassfish .jersey .linking .mapping .ResourceMappingContext ;
5760
5861/**
@@ -67,33 +70,39 @@ class FieldProcessor<T> {
6770 private EntityDescriptor instanceDescriptor ;
6871 private static final Logger log = Logger .getLogger (FieldProcessor .class .getName ());
6972
70- public FieldProcessor (Class <T > c ) {
73+ FieldProcessor (Class <T > c ) {
7174 instanceDescriptor = EntityDescriptor .getInstance (c );
7275 }
7376
7477 /**
7578 * Inject any {@link org.glassfish.jersey.linking.InjectLink} annotated fields in the supplied entity and
7679 * recursively process its fields.
77- * @param entity the entity object returned by the resource method
80+ *
81+ * @param entity the entity object returned by the resource method
7882 * @param uriInfo the uriInfo for the request
83+ * @param rmc the ResourceMappingContext used for building URIs
84+ * @param rlcc the ResourceLinkContributionContext used to find link contributors
7985 */
80- public void processLinks (T entity , UriInfo uriInfo , ResourceMappingContext rmc ) {
86+ void processLinks (T entity , UriInfo uriInfo , ResourceMappingContext rmc , ResourceLinkContributionContext rlcc ) {
8187 Set <Object > processed = new HashSet <Object >();
8288 Object resource = uriInfo .getMatchedResources ().get (0 );
83- processLinks (entity , resource , entity , processed , uriInfo , rmc );
89+ processLinks (entity , resource , entity , processed , uriInfo , rmc , rlcc );
8490 }
8591
8692 /**
8793 * Inject any {@link org.glassfish.jersey.linking.InjectLink} annotated fields in the supplied instance. Called
8894 * once for the entity and then recursively for each member and field.
89- * @param entity
95+ *
96+ * @param entity the entity object returned by the resource method
9097 * @param processed a list of already processed objects, used to break
91- * recursion when processing circular references.
92- * @param uriInfo
98+ * recursion when processing circular references.
99+ * @param uriInfo the uriInfo for the request
100+ * @param rmc the ResourceMappingContext used for building URIs
101+ * @param rlcc the ResourceLinkContributionContext used to find link contributors
93102 */
94103 private void processLinks (Object entity , Object resource , Object instance ,
95- Set <Object > processed , UriInfo uriInfo ,
96- ResourceMappingContext rmc ) {
104+ Set <Object > processed , UriInfo uriInfo ,
105+ ResourceMappingContext rmc , ResourceLinkContributionContext rlcc ) {
97106
98107 try {
99108 if (instance == null || processed .contains (instance )) {
@@ -121,14 +130,23 @@ private void processLinks(Object entity, Object resource, Object instance,
121130 } else if (field instanceof InjectLinksFieldDescriptor ) {
122131
123132 InjectLinksFieldDescriptor linksField = (InjectLinksFieldDescriptor ) field ;
124- List <Link > list = new ArrayList <Link >();
133+ List <Link > list = new ArrayList <>();
125134 for (InjectLinkFieldDescriptor linkField : linksField .getLinksToInject ()) {
126135 if (ELLinkBuilder .evaluateCondition (linkField .getCondition (), entity , resource , instance )) {
127136 URI uri = ELLinkBuilder .buildURI (linkField , entity , resource , instance , uriInfo , rmc );
128137 Link link = linkField .getLink (uri );
129138 list .add (link );
130139 }
131140 }
141+ List <ProvideLinkDescriptor > linkContributors = rlcc .getContributorsFor (instance .getClass ());
142+ for (ProvideLinkDescriptor linkContributor : linkContributors ) {
143+ if (ELLinkBuilder .evaluateCondition (linkContributor .getCondition (),
144+ entity , linkContributor .getResource (), instance )) {
145+ URI uri = ELLinkBuilder .buildURI (linkContributor , entity , resource , instance , uriInfo , rmc );
146+ Link link = linkContributor .getLink (uri );
147+ list .add (link );
148+ }
149+ }
132150
133151 linksField .setPropertyValue (instance , list );
134152 }
@@ -139,25 +157,25 @@ private void processLinks(Object entity, Object resource, Object instance,
139157 if (instanceClass .isArray () && Object [].class .isAssignableFrom (instanceClass )) {
140158 Object array [] = (Object []) instance ;
141159 for (Object member : array ) {
142- processMember (entity , resource , member , processed , uriInfo , rmc );
160+ processMember (entity , resource , member , processed , uriInfo , rmc , rlcc );
143161 }
144162 } else if (instance instanceof Iterable ) {
145163 Iterable iterable = (Iterable ) instance ;
146164 for (Object member : iterable ) {
147- processMember (entity , resource , member , processed , uriInfo , rmc );
165+ processMember (entity , resource , member , processed , uriInfo , rmc , rlcc );
148166 }
149167 } else if (instance instanceof Map ) {
150168 Map map = (Map ) instance ;
151169 for (Object member : map .entrySet ()) {
152- processMember (entity , resource , member , processed , uriInfo , rmc );
170+ processMember (entity , resource , member , processed , uriInfo , rmc , rlcc );
153171 }
154172 }
155173
156174 // Recursively process all member fields
157175 for (FieldDescriptor member : instanceDescriptor .getNonLinkFields ()) {
158176
159177 if (fieldSuitableForIntrospection (member )) {
160- processMember (entity , resource , member .getFieldValue (instance ), processed , uriInfo , rmc );
178+ processMember (entity , resource , member .getFieldValue (instance ), processed , uriInfo , rmc , rlcc );
161179 }
162180 }
163181
@@ -174,10 +192,10 @@ private boolean fieldSuitableForIntrospection(FieldDescriptor member) {
174192 }
175193
176194 private void processMember (Object entity , Object resource , Object member , Set <Object > processed , UriInfo uriInfo ,
177- ResourceMappingContext rmc ) {
195+ ResourceMappingContext rmc , ResourceLinkContributionContext rlcc ) {
178196 if (member != null ) {
179- FieldProcessor proc = new FieldProcessor (member .getClass ());
180- proc .processLinks (entity , resource , member , processed , uriInfo , rmc );
197+ FieldProcessor <?> proc = new FieldProcessor (member .getClass ());
198+ proc .processLinks (entity , resource , member , processed , uriInfo , rmc , rlcc );
181199 }
182200 }
183201
0 commit comments