Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Sign In

DSpace / DSpace / 7170

21 Oct 2019 - 14:31 coverage increased (+1.1%) to 36.543%
7170

Pull #2529

travis-ci

9181eb84f9c35729a3bad740fb7f9d93?size=18&default=identiconweb-flow
Evaluated feedback on scripts and processes endpoints and model classes. Added javadoc, fixed tests and made improvements to various parts of the Scripts and processes feature
Pull Request #2529: Scripts and processes endpoint

439 of 666 new or added lines in 29 files covered. (65.92%)

888 existing lines in 25 files now uncovered.

28781 of 78760 relevant lines covered (36.54%)

0.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.4
/dspace-api/src/main/java/org/dspace/content/RelationshipServiceImpl.java
1
/**
2
 * The contents of this file are subject to the license and copyright
3
 * detailed in the LICENSE and NOTICE files at the root of the source
4
 * tree and available online at
5
 *
6
 * http://www.dspace.org/license/
7
 */
8
package org.dspace.content;
9

10
import java.sql.SQLException;
11
import java.util.Collections;
12
import java.util.Comparator;
13
import java.util.LinkedList;
14
import java.util.List;
15

16
import org.apache.commons.collections4.CollectionUtils;
17
import org.apache.commons.lang3.StringUtils;
18
import org.apache.logging.log4j.LogManager;
19
import org.apache.logging.log4j.Logger;
20
import org.dspace.authorize.AuthorizeException;
21
import org.dspace.authorize.service.AuthorizeService;
22
import org.dspace.content.dao.RelationshipDAO;
23
import org.dspace.content.service.ItemService;
24
import org.dspace.content.service.RelationshipService;
25
import org.dspace.content.service.RelationshipTypeService;
26
import org.dspace.content.virtual.VirtualMetadataPopulator;
27
import org.dspace.core.Constants;
28
import org.dspace.core.Context;
29
import org.springframework.beans.factory.annotation.Autowired;
30

31
public class RelationshipServiceImpl implements RelationshipService {
1×
32

33
    private static final Logger log = LogManager.getLogger();
1×
34

35
    @Autowired(required = true)
36
    protected RelationshipDAO relationshipDAO;
37

38
    @Autowired(required = true)
39
    protected AuthorizeService authorizeService;
40

41
    @Autowired(required = true)
42
    protected ItemService itemService;
43

44
    @Autowired(required = true)
45
    protected RelationshipTypeService relationshipTypeService;
46

47
    @Autowired
48
    private VirtualMetadataPopulator virtualMetadataPopulator;
49

50
    @Override
51
    public Relationship create(Context context) throws SQLException, AuthorizeException {
52
        if (!authorizeService.isAdmin(context)) {
1×
53
            throw new AuthorizeException(
!
54
                "Only administrators can modify relationship");
55
        }
56
        return relationshipDAO.create(context, new Relationship());
1×
57
    }
58

59
    @Override
60
    public Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
61
                               int leftPlace, int rightPlace) throws AuthorizeException, SQLException {
62
        return create(c, leftItem, rightItem, relationshipType, leftPlace, rightPlace, null, null);
1×
63
    }
64

65
    @Override
66
    public Relationship create(Context c, Item leftItem, Item rightItem, RelationshipType relationshipType,
67
                               int leftPlace, int rightPlace, String leftwardValue, String rightwardValue)
68
            throws AuthorizeException, SQLException {
69
        Relationship relationship = new Relationship();
1×
70
        relationship.setLeftItem(leftItem);
1×
71
        relationship.setRightItem(rightItem);
1×
72
        relationship.setRelationshipType(relationshipType);
1×
73
        relationship.setLeftPlace(leftPlace);
1×
74
        relationship.setRightPlace(rightPlace);
1×
75
        relationship.setLeftwardValue(leftwardValue);
1×
76
        relationship.setRightwardValue(rightwardValue);
1×
77
        return create(c, relationship);
1×
78
    }
79

80
    @Override
81
    public Relationship create(Context context, Relationship relationship) throws SQLException, AuthorizeException {
82
        if (isRelationshipValidToCreate(context, relationship)) {
1×
83
            if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) ||
1×
84
                authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) {
1×
85
                updatePlaceInRelationship(context, relationship, true);
1×
86
                return relationshipDAO.create(context, relationship);
1×
87
            } else {
UNCOV
88
                throw new AuthorizeException(
!
89
                    "You do not have write rights on this relationship's items");
90
            }
91

92
        } else {
UNCOV
93
            throw new IllegalArgumentException("The relationship given was not valid");
!
94
        }
95
    }
96

97
    @Override
98
    public void updatePlaceInRelationship(Context context, Relationship relationship, boolean isCreation)
99
        throws SQLException, AuthorizeException {
100
        Item leftItem = relationship.getLeftItem();
1×
101
        List<Relationship> leftRelationships = findByItemAndRelationshipType(context,
1×
102
                                                                             leftItem,
103
                                                                             relationship.getRelationshipType(), true);
1×
104
        Item rightItem = relationship.getRightItem();
1×
105
        List<Relationship> rightRelationships = findByItemAndRelationshipType(context,
1×
106
                                                                              rightItem,
107
                                                                              relationship.getRelationshipType(),
1×
108
                                                                              false);
109

110
        context.turnOffAuthorisationSystem();
1×
111
        //If useForPlace for the leftwardType is false for the relationshipType,
112
        // we need to sort the relationships here based on leftplace.
113
        if (!virtualMetadataPopulator.isUseForPlaceTrueForRelationshipType(relationship.getRelationshipType(), true)) {
1×
114
            if (!leftRelationships.isEmpty()) {
1×
UNCOV
115
                leftRelationships.sort(Comparator.comparingInt(Relationship::getLeftPlace));
!
UNCOV
116
                for (int i = 0; i < leftRelationships.size(); i++) {
!
UNCOV
117
                    leftRelationships.get(i).setLeftPlace(i);
!
118
                }
UNCOV
119
                relationship.setLeftPlace(leftRelationships.size());
!
120
            } else {
121
                relationship.setLeftPlace(0);
1×
122
            }
123
        } else {
124
            updateItem(context, leftItem);
1×
125

126
        }
127

128
        //If useForPlace for the rightwardType is false for the relationshipType,
129
        // we need to sort the relationships here based on the rightplace.
130
        if (!virtualMetadataPopulator.isUseForPlaceTrueForRelationshipType(relationship.getRelationshipType(), false)) {
1×
131
            if (!rightRelationships.isEmpty()) {
1×
132
                rightRelationships.sort(Comparator.comparingInt(Relationship::getRightPlace));
1×
133
                for (int i = 0; i < rightRelationships.size(); i++) {
1×
134
                    rightRelationships.get(i).setRightPlace(i);
1×
135
                }
136
                relationship.setRightPlace(rightRelationships.size());
1×
137
            } else {
138
                relationship.setRightPlace(0);
1×
139
            }
140

141
        } else {
UNCOV
142
            updateItem(context, rightItem);
!
143

144
        }
145

146
        if (isCreation) {
1×
147
            handleCreationPlaces(context, relationship);
1×
148
        }
149
        context.restoreAuthSystemState();
1×
150

151
    }
1×
152

153
    @Override
154
    public void updateItem(Context context, Item relatedItem)
155
        throws SQLException, AuthorizeException {
156
        relatedItem.setMetadataModified();
1×
157
        itemService.update(context, relatedItem);
1×
158
    }
1×
159

160

161
    //Sets the places for the Relationship properly if the updatePlaceInRelationship was called for a new creation
162
    //of this Relationship
163
    private void handleCreationPlaces(Context context, Relationship relationship) throws SQLException {
164
        List<Relationship> leftRelationships;
165
        List<Relationship> rightRelationships;
166
        leftRelationships = findByItemAndRelationshipType(context,
1×
167
                                                          relationship.getLeftItem(),
1×
168
                                                          relationship.getRelationshipType(), true);
1×
169
        rightRelationships = findByItemAndRelationshipType(context,
1×
170
                                                           relationship.getRightItem(),
1×
171
                                                           relationship.getRelationshipType(),
1×
172
                                                           false);
173
        leftRelationships.sort((o1, o2) -> o2.getLeftPlace() - o1.getLeftPlace());
1×
174
        rightRelationships.sort((o1, o2) -> o2.getRightPlace() - o1.getRightPlace());
1×
175

176
        if (!leftRelationships.isEmpty()) {
1×
177
            relationship.setLeftPlace(leftRelationships.get(0).getLeftPlace() + 1);
1×
178
        } else {
179
            relationship.setLeftPlace(0);
1×
180
        }
181

182
        if (!rightRelationships.isEmpty()) {
1×
183
            relationship.setRightPlace(rightRelationships.get(0).getRightPlace() + 1);
1×
184
        } else {
185
            relationship.setRightPlace(0);
1×
186
        }
187
    }
1×
188

189
    @Override
190
    public int findLeftPlaceByLeftItem(Context context, Item item) throws SQLException {
191
        return relationshipDAO.findLeftPlaceByLeftItem(context, item);
1×
192
    }
193

194
    @Override
195
    public int findRightPlaceByRightItem(Context context, Item item) throws SQLException {
196
        return relationshipDAO.findRightPlaceByRightItem(context, item);
1×
197
    }
198

199
    private boolean isRelationshipValidToCreate(Context context, Relationship relationship) throws SQLException {
200
        RelationshipType relationshipType = relationship.getRelationshipType();
1×
201

202
        if (!verifyEntityTypes(relationship.getLeftItem(), relationshipType.getLeftType())) {
1×
203
            log.warn("The relationship has been deemed invalid since the leftItem" +
!
204
                         " and leftType do no match on entityType");
UNCOV
205
            logRelationshipTypeDetailsForError(relationshipType);
!
UNCOV
206
            return false;
!
207
        }
208
        if (!verifyEntityTypes(relationship.getRightItem(), relationshipType.getRightType())) {
1×
209
            log.warn("The relationship has been deemed invalid since the rightItem" +
!
210
                         " and rightType do no match on entityType");
UNCOV
211
            logRelationshipTypeDetailsForError(relationshipType);
!
UNCOV
212
            return false;
!
213
        }
214
        if (!verifyMaxCardinality(context, relationship.getLeftItem(),
1×
215
                                  relationshipType.getLeftMaxCardinality(), relationshipType)) {
1×
216
            log.warn("The relationship has been deemed invalid since the left item has more" +
!
217
                         " relationships than the left max cardinality allows after we'd store this relationship");
UNCOV
218
            logRelationshipTypeDetailsForError(relationshipType);
!
UNCOV
219
            return false;
!
220
        }
221
        if (!verifyMaxCardinality(context, relationship.getRightItem(),
1×
222
                                  relationshipType.getRightMaxCardinality(), relationshipType)) {
1×
223
            log.warn("The relationship has been deemed invalid since the right item has more" +
!
224
                         " relationships than the right max cardinality allows after we'd store this relationship");
225
            logRelationshipTypeDetailsForError(relationshipType);
!
226
            return false;
!
227
        }
228
        return true;
1×
229
    }
230

231
    private void logRelationshipTypeDetailsForError(RelationshipType relationshipType) {
232
        log.warn("The relationshipType's ID is: " + relationshipType.getID());
!
UNCOV
233
        log.warn("The relationshipType's leftward type is: " + relationshipType.getLeftwardType());
!
UNCOV
234
        log.warn("The relationshipType's rightward type is: " + relationshipType.getRightwardType());
!
UNCOV
235
        log.warn("The relationshipType's left entityType label is: " + relationshipType.getLeftType().getLabel());
!
UNCOV
236
        log.warn("The relationshipType's right entityType label is: " + relationshipType.getRightType().getLabel());
!
UNCOV
237
        log.warn("The relationshipType's left min cardinality is: " + relationshipType.getLeftMinCardinality());
!
UNCOV
238
        log.warn("The relationshipType's left max cardinality is: " + relationshipType.getLeftMaxCardinality());
!
UNCOV
239
        log.warn("The relationshipType's right min cardinality is: " + relationshipType.getRightMinCardinality());
!
240
        log.warn("The relationshipType's right max cardinality is: " + relationshipType.getRightMaxCardinality());
!
UNCOV
241
    }
!
242

243
    private boolean verifyMaxCardinality(Context context, Item itemToProcess,
244
                                         Integer maxCardinality,
245
                                         RelationshipType relationshipType) throws SQLException {
246
        List<Relationship> rightRelationships = findByItemAndRelationshipType(context, itemToProcess, relationshipType,
1×
247
                                                                              false);
248
        if (maxCardinality != null && rightRelationships.size() >= maxCardinality) {
1×
UNCOV
249
            return false;
!
250
        }
251
        return true;
1×
252
    }
253

254
    private boolean verifyEntityTypes(Item itemToProcess, EntityType entityTypeToProcess) {
255
        List<MetadataValue> list = itemService.getMetadata(itemToProcess, "relationship", "type", null, Item.ANY);
1×
256
        if (list.isEmpty()) {
1×
UNCOV
257
            return false;
!
258
        }
259
        String leftEntityType = list.get(0).getValue();
1×
260
        return StringUtils.equals(leftEntityType, entityTypeToProcess.getLabel());
1×
261
    }
262

263
    public Relationship find(Context context, int id) throws SQLException {
264
        Relationship relationship = relationshipDAO.findByID(context, Relationship.class, id);
1×
265
        return relationship;
1×
266
    }
267

268
    @Override
269
    public List<Relationship> findByItem(Context context, Item item) throws SQLException {
270

271
        List<Relationship> list = relationshipDAO.findByItem(context, item);
1×
272

273
        list.sort((o1, o2) -> {
1×
274
            int relationshipType = o1.getRelationshipType().getLeftwardType()
1×
275
                                     .compareTo(o2.getRelationshipType().getLeftwardType());
1×
276
            if (relationshipType != 0) {
1×
277
                return relationshipType;
1×
278
            } else {
279
                if (o1.getLeftItem() == item) {
1×
280
                    return o1.getLeftPlace() - o2.getLeftPlace();
1×
281
                } else {
282
                    return o1.getRightPlace() - o2.getRightPlace();
1×
283
                }
284
            }
285
        });
286
        return list;
1×
287
    }
288

289
    @Override
290
    public List<Relationship> findAll(Context context) throws SQLException {
291
        return relationshipDAO.findAll(context, Relationship.class);
1×
292
    }
293

294
    @Override
295
    public void update(Context context, Relationship relationship) throws SQLException, AuthorizeException {
296
        update(context, Collections.singletonList(relationship));
1×
297

298
    }
1×
299

300
    @Override
301
    public void update(Context context, List<Relationship> relationships) throws SQLException, AuthorizeException {
302
        if (CollectionUtils.isNotEmpty(relationships)) {
1×
303
            for (Relationship relationship : relationships) {
1×
304
                if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) ||
1×
305
                    authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) {
1×
306
                    if (isRelationshipValidToCreate(context, relationship)) {
1×
307
                        relationshipDAO.save(context, relationship);
1×
308
                    }
309
                } else {
UNCOV
310
                    throw new AuthorizeException("You do not have write rights on this relationship's items");
!
311
                }
312
            }
1×
313
        }
314
    }
1×
315

316
    @Override
317
    public void delete(Context context, Relationship relationship) throws SQLException, AuthorizeException {
318
        if (isRelationshipValidToDelete(context, relationship)) {
1×
319
            // To delete a relationship, a user must have WRITE permissions on one of the related Items
320
            if (authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(), Constants.WRITE) ||
1×
321
                authorizeService.authorizeActionBoolean(context, relationship.getRightItem(), Constants.WRITE)) {
!
322
                relationshipDAO.delete(context, relationship);
1×
323
                updatePlaceInRelationship(context, relationship, false);
1×
324
            } else {
UNCOV
325
                throw new AuthorizeException(
!
326
                    "You do not have write rights on this relationship's items");
327
            }
328

329
        } else {
UNCOV
330
            throw new IllegalArgumentException("The relationship given was not valid");
!
331
        }
332
    }
1×
333

334
    private boolean isRelationshipValidToDelete(Context context, Relationship relationship) throws SQLException {
335
        if (relationship == null) {
1×
336
            log.warn("The relationship has been deemed invalid since the relation was null");
!
UNCOV
337
            return false;
!
338
        }
339
        if (relationship.getID() == null) {
1×
UNCOV
340
            log.warn("The relationship has been deemed invalid since the ID" +
!
341
                         " off the given relationship was null");
UNCOV
342
            return false;
!
343
        }
344
        if (this.find(context, relationship.getID()) == null) {
1×
345
            log.warn("The relationship has been deemed invalid since the relationship" +
!
346
                         " is not present in the DB with the current ID");
UNCOV
347
            logRelationshipTypeDetailsForError(relationship.getRelationshipType());
!
UNCOV
348
            return false;
!
349
        }
350
        if (!checkMinCardinality(context, relationship.getLeftItem(),
1×
351
                                 relationship, relationship.getRelationshipType().getLeftMinCardinality(), true)) {
1×
UNCOV
352
            log.warn("The relationship has been deemed invalid since the leftMinCardinality" +
!
353
                         " constraint would be violated upon deletion");
354
            logRelationshipTypeDetailsForError(relationship.getRelationshipType());
!
UNCOV
355
            return false;
!
356
        }
357

358
        if (!checkMinCardinality(context, relationship.getRightItem(),
1×
359
                                 relationship, relationship.getRelationshipType().getRightMinCardinality(), false)) {
1×
UNCOV
360
            log.warn("The relationship has been deemed invalid since the rightMinCardinality" +
!
361
                         " constraint would be violated upon deletion");
UNCOV
362
            logRelationshipTypeDetailsForError(relationship.getRelationshipType());
!
UNCOV
363
            return false;
!
364
        }
365
        return true;
1×
366
    }
367

368
    private boolean checkMinCardinality(Context context, Item item,
369
                                        Relationship relationship,
370
                                        Integer minCardinality, boolean isLeft) throws SQLException {
371
        List<Relationship> list = this
1×
372
            .findByItemAndRelationshipType(context, item, relationship.getRelationshipType(), isLeft);
1×
373
        if (minCardinality != null && !(list.size() > minCardinality)) {
1×
UNCOV
374
            return false;
!
375
        }
376
        return true;
1×
377
    }
378

379
    public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
380
                                                            RelationshipType relationshipType, boolean isLeft)
381

382
        throws SQLException {
383
        List<Relationship> list = this.findByItem(context, item);
1×
384
        List<Relationship> listToReturn = new LinkedList<>();
1×
385
        for (Relationship relationship : list) {
1×
386
            if (isLeft) {
1×
387
                if (StringUtils
1×
388
                    .equals(
1×
389
                        relationship.getRelationshipType().getLeftwardType(), relationshipType.getLeftwardType())
1×
390
                ) {
391
                    listToReturn.add(relationship);
1×
392
                }
393
            } else {
394
                if (StringUtils
1×
395
                    .equals(
1×
396
                        relationship.getRelationshipType().getRightwardType(), relationshipType.getRightwardType())
1×
397
                ) {
398
                    listToReturn.add(relationship);
1×
399
                }
400
            }
401
        }
1×
402
        return listToReturn;
1×
403
    }
404

405
    @Override
406
    public List<Relationship> findByItemAndRelationshipType(Context context, Item item,
407
                                                            RelationshipType relationshipType)
408

409
        throws SQLException {
410
        List<Relationship> list = this.findByItem(context, item);
1×
411
        List<Relationship> listToReturn = new LinkedList<>();
1×
412
        for (Relationship relationship : list) {
1×
413
            if (relationship.getRelationshipType().equals(relationshipType)) {
1×
414
                listToReturn.add(relationship);
1×
415
            }
416
        }
1×
417
        return listToReturn;
1×
418
    }
419

420
    @Override
421
    public List<Relationship> findByRelationshipType(Context context, RelationshipType relationshipType)
422
        throws SQLException {
423
        return relationshipDAO.findByRelationshipType(context, relationshipType);
1×
424
    }
425

426

427
}
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
BLOG · TWITTER · Legal & Privacy · Supported CI Services · What's a CI service? · Automated Testing

© 2019 Coveralls, LLC