Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Genesys Backend
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
45
Issues
45
List
Boards
Labels
Service Desk
Milestones
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Genesys PGR
Genesys Backend
Commits
ebb86823
Commit
ebb86823
authored
Oct 12, 2018
by
Matija Obreza
1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
AccessionRefs can be manually re-linked, but are automatically cleared
- Aspect on delete Accession sets AccessionRef#accession to null
parent
3aa5a897
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
323 additions
and
295 deletions
+323
-295
src/main/java/org/genesys/catalog/service/DatasetService.java
...main/java/org/genesys/catalog/service/DatasetService.java
+27
-8
src/main/java/org/genesys/catalog/service/impl/DatasetServiceImpl.java
.../org/genesys/catalog/service/impl/DatasetServiceImpl.java
+57
-18
src/main/java/org/genesys2/server/model/genesys/AccessionData.java
...java/org/genesys2/server/model/genesys/AccessionData.java
+0
-14
src/main/java/org/genesys2/server/model/genesys/AccessionRef.java
.../java/org/genesys2/server/model/genesys/AccessionRef.java
+18
-1
src/main/java/org/genesys2/server/model/impl/Subset.java
src/main/java/org/genesys2/server/model/impl/Subset.java
+3
-4
src/main/java/org/genesys2/server/persistence/AccessionRepositoryCustom.java
...enesys2/server/persistence/AccessionRepositoryCustom.java
+2
-0
src/main/java/org/genesys2/server/persistence/AccessionRepositoryCustomImpl.java
...ys2/server/persistence/AccessionRepositoryCustomImpl.java
+15
-0
src/main/java/org/genesys2/server/service/SubsetService.java
src/main/java/org/genesys2/server/service/SubsetService.java
+21
-1
src/main/java/org/genesys2/server/service/impl/SubsetServiceImpl.java
...a/org/genesys2/server/service/impl/SubsetServiceImpl.java
+94
-16
src/main/java/org/genesys2/server/service/worker/AccessionRefAspect.java
...rg/genesys2/server/service/worker/AccessionRefAspect.java
+11
-79
src/test/java/org/genesys/test/catalog/api/v0/DatasetControllerTest.java
...rg/genesys/test/catalog/api/v0/DatasetControllerTest.java
+2
-15
src/test/java/org/genesys/test/catalog/services/AbstractDatasetServiceTest.java
...sys/test/catalog/services/AbstractDatasetServiceTest.java
+3
-21
src/test/java/org/genesys/test/catalog/services/DatasetServiceTest.java
...org/genesys/test/catalog/services/DatasetServiceTest.java
+58
-109
src/test/java/org/genesys/test/server/api/v1/SubsetRestControllerTest.java
.../genesys/test/server/api/v1/SubsetRestControllerTest.java
+12
-9
No files found.
src/main/java/org/genesys/catalog/service/DatasetService.java
View file @
ebb86823
...
...
@@ -15,9 +15,13 @@
*/
package
org.genesys.catalog.service
;
import
java.io.IOException
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.UUID
;
import
org.genesys.catalog.exceptions.NotFoundElement
;
import
org.genesys2.server.model.genesys.Accession
;
import
org.genesys2.server.model.genesys.AccessionRef
;
import
org.genesys.catalog.model.dataset.Dataset
;
import
org.genesys.catalog.model.dataset.DatasetCreator
;
import
org.genesys.catalog.model.dataset.DatasetLocation
;
...
...
@@ -27,18 +31,14 @@ import org.genesys.filerepository.InvalidRepositoryFileDataException;
import
org.genesys.filerepository.InvalidRepositoryPathException
;
import
org.genesys.filerepository.NoSuchRepositoryFileException
;
import
org.genesys.filerepository.model.RepositoryFile
;
import
org.genesys2.server.model.genesys.AccessionId
;
import
org.genesys2.server.model.genesys.Accession
;
import
org.genesys2.server.model.genesys.AccessionRef
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.io.IOException
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.UUID
;
/**
* The Interface DatasetService.
*/
...
...
@@ -262,8 +262,19 @@ public interface DatasetService {
*/
List
<
Object
[]>
lastPublished
();
/**
* Rematch dataset accessions for all datasets.
*/
void
rematchDatasetAccessions
();
/**
* Rematch dataset accessions.
*
* @param dataset the dataset
* @return the dataset
*/
Dataset
rematchDatasetAccessions
(
Dataset
dataset
);
/**
* Create DatasetCreator for Dataset.
*
...
...
@@ -415,4 +426,12 @@ public interface DatasetService {
*/
DatasetLocation
updateLocation
(
Dataset
dataset
,
DatasetLocation
input
)
throws
NotFoundElement
;
/**
* Clear accession references across all Datasets for specified accessions.
*
* @param accessions the accessions
* @return the int
*/
int
clearAccessionRefs
(
Collection
<
Accession
>
accessions
);
}
src/main/java/org/genesys/catalog/service/impl/DatasetServiceImpl.java
View file @
ebb86823
...
...
@@ -23,23 +23,25 @@ import java.io.IOException;
import
java.nio.file.Paths
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.UUID
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.stream.Collectors
;
import
com.querydsl.core.types.Predicate
;
import
org.apache.commons.lang.StringUtils
;
import
org.genesys.blocks.security.service.CustomAclService
;
import
org.genesys.catalog.exceptions.InvalidApiUsageException
;
import
org.genesys.catalog.exceptions.NotFoundElement
;
import
org.genesys.catalog.model.Partner
;
import
org.genesys2.server.model.genesys.AccessionRef
;
import
org.genesys.catalog.model.dataset.Dataset
;
import
org.genesys.catalog.model.dataset.DatasetCreator
;
import
org.genesys.catalog.model.dataset.DatasetLocation
;
import
org.genesys.catalog.model.dataset.DatasetVersions
;
import
org.genesys.catalog.model.dataset.QDataset
;
import
org.genesys.catalog.model.dataset.*
;
import
org.genesys.catalog.model.filters.DatasetFilter
;
import
org.genesys.catalog.model.traits.Descriptor
;
import
org.genesys.catalog.persistence.dataset.DatasetCreatorRepository
;
...
...
@@ -55,7 +57,7 @@ import org.genesys.filerepository.service.RepositoryService;
import
org.genesys2.server.model.PublishState
;
import
org.genesys2.server.model.UserRole
;
import
org.genesys2.server.model.genesys.Accession
;
import
org.genesys2.server.model.genesys.Accession
Id
;
import
org.genesys2.server.model.genesys.Accession
Ref
;
import
org.genesys2.server.persistence.AccessionRepository
;
import
org.genesys2.server.security.SecurityUtils
;
import
org.genesys2.server.service.DownloadService
;
...
...
@@ -64,16 +66,23 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.dao.ConcurrencyFailureException
;
import
org.springframework.dao.DataIntegrityViolationException
;
import
org.springframework.data.domain.*
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.PageImpl
;
import
org.springframework.data.domain.PageRequest
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.domain.Sort
;
import
org.springframework.security.access.prepost.PostAuthorize
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.security.acls.domain.BasePermission
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Isolation
;
import
org.springframework.transaction.annotation.Propagation
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.web.multipart.MultipartFile
;
import
com.google.common.collect.Lists
;
import
com.querydsl.core.BooleanBuilder
;
import
com.querydsl.core.types.Predicate
;
/**
...
...
@@ -145,7 +154,7 @@ public class DatasetServiceImpl implements DatasetService {
dataset
.
setCrops
(
source
.
getCrops
());
if
(
source
.
getAccessionRefs
()
!=
null
&&
!
source
.
getAccessionRefs
().
isEmpty
())
{
dataset
.
setAccessionRefs
(
lookupMatchingAccessions
(
new
HashSet
<>(
source
.
getAccessionRefs
()
)));
dataset
.
setAccessionRefs
(
lookupMatchingAccessions
(
source
.
getAccessionRefs
(
)));
}
copyDescriptors
(
dataset
,
source
.
getDescriptors
());
...
...
@@ -193,7 +202,7 @@ public class DatasetServiceImpl implements DatasetService {
LOG
.
info
(
"Update AccessionIdentifiers. Input dataset: {}, input accessionRefs {}"
,
dataset
,
accessionRefs
);
dataset
=
loadDataset
(
dataset
);
dataset
.
getAccessionRefs
().
clear
();
dataset
.
setAccessionRefs
(
lookupMatchingAccessions
(
new
HashSet
<>(
accessionRefs
)
));
dataset
.
setAccessionRefs
(
lookupMatchingAccessions
(
accessionRefs
));
return
lazyLoad
(
datasetRepository
.
save
(
dataset
));
}
...
...
@@ -466,7 +475,7 @@ public class DatasetServiceImpl implements DatasetService {
throw
new
NotFoundElement
(
"Dataset doesn't exist"
);
}
loadedDataset
.
setState
(
PublishState
.
DRAFT
);
loadedDataset
.
setAccessionRefs
(
lookupMatchingAccessions
(
new
HashSet
<>(
accessionRefs
)
));
loadedDataset
.
setAccessionRefs
(
lookupMatchingAccessions
(
accessionRefs
));
return
lazyLoad
(
datasetRepository
.
save
(
loadedDataset
));
}
...
...
@@ -768,6 +777,7 @@ public class DatasetServiceImpl implements DatasetService {
* Looking for matching Accession and then sets that to AccessionRef
*
* @param accessionRefs the accessionRefs
*
* @return accessionRefs with matching accessions from Genesys
*/
private
Set
<
AccessionRef
>
lookupMatchingAccessions
(
final
Set
<
AccessionRef
>
accessionRefs
)
{
...
...
@@ -776,20 +786,20 @@ public class DatasetServiceImpl implements DatasetService {
LOG
.
info
(
"Found {} matches for {} identifiers"
,
foundAccessions
.
size
(),
accessionRefs
.
size
());
accessionRefs
.
forEach
(
accei
->
{
accessionRefs
.
forEach
(
ref
->
{
Accession
foundAccession
=
foundAccessions
.
stream
().
filter
(
a
->
{
return
StringUtils
.
equalsIgnoreCase
(
a
.
getInstCode
(),
accei
.
getInstCode
())
return
StringUtils
.
equalsIgnoreCase
(
a
.
getInstCode
(),
ref
.
getInstCode
())
&&
(
// when DOI provided
(
accei
.
getDoi
()
!=
null
&&
a
.
getDoi
()
!=
null
&&
StringUtils
.
equals
(
a
.
getDoi
(),
accei
.
getDoi
()))
(
ref
.
getDoi
()
!=
null
&&
a
.
getDoi
()
!=
null
&&
StringUtils
.
equals
(
a
.
getDoi
(),
ref
.
getDoi
()))
// OR when without DOI
||
(
StringUtils
.
equalsIgnoreCase
(
a
.
getAccessionNumber
(),
accei
.
getAcceNumb
())
&&
StringUtils
.
equalsIgnoreCase
(
a
.
getGenus
(),
accei
.
getGenus
()))
(
StringUtils
.
equalsIgnoreCase
(
a
.
getAccessionNumber
(),
ref
.
getAcceNumb
())
&&
StringUtils
.
equalsIgnoreCase
(
a
.
getGenus
(),
ref
.
getGenus
()))
);
}).
findFirst
().
orElse
(
null
);
accei
.
setAccession
(
foundAccession
);
ref
.
setAccession
(
foundAccession
);
if
(
foundAccession
==
null
)
{
LOG
.
debug
(
"No match for {}"
,
accei
);
LOG
.
debug
(
"No match for {}"
,
ref
);
}
});
...
...
@@ -799,14 +809,43 @@ public class DatasetServiceImpl implements DatasetService {
@Override
@Transactional
(
readOnly
=
false
)
@PreAuthorize
(
"hasRole('ADMINISTRATOR')"
)
public
void
rematchDatasetAccessions
()
{
datasetRepository
.
findAll
().
forEach
(
dataset
->
{
LOG
.
warn
(
"Linking {} accessions with dataset {}"
,
dataset
.
getAccessionCount
(),
dataset
.
getId
());
dataset
.
setAccessionRefs
(
lookupMatchingAccessions
(
new
HashSet
<>(
dataset
.
getAccessionRefs
())));
datasetRepository
.
save
(
dataset
);
rematchDatasetAccessions
(
dataset
);
});
}
@Override
@Transactional
(
readOnly
=
false
)
@PreAuthorize
(
"hasRole('ADMINISTRATOR') or hasPermission(#dataset, 'write')"
)
public
Dataset
rematchDatasetAccessions
(
Dataset
dataset
)
{
dataset
=
datasetRepository
.
findByUuid
(
dataset
.
getUuid
());
LOG
.
warn
(
"Linking {} accessions with dataset {}"
,
dataset
.
getAccessionCount
(),
dataset
.
getId
());
dataset
.
setAccessionRefs
(
lookupMatchingAccessions
(
dataset
.
getAccessionRefs
()));
return
datasetRepository
.
save
(
dataset
);
}
@Override
@Transactional
(
readOnly
=
false
,
propagation
=
Propagation
.
REQUIRED
,
isolation
=
Isolation
.
READ_UNCOMMITTED
)
public
int
clearAccessionRefs
(
Collection
<
Accession
>
accessions
)
{
Set
<
UUID
>
uuids
=
accessions
.
stream
().
map
(
a
->
a
.
getUuid
()).
collect
(
Collectors
.
toSet
());
final
Iterable
<
Dataset
>
datasets
=
datasetRepository
.
findAll
(
dataset
.
accessionRefs
.
any
().
accession
.
in
(
accessions
));
AtomicInteger
updates
=
new
AtomicInteger
(
0
);
datasets
.
forEach
(
dataset
->
{
dataset
.
getAccessionRefs
().
stream
()
// filter for matching accessions
.
filter
(
ref
->
ref
.
getAccession
()
!=
null
&&
uuids
.
contains
(
ref
.
getAccession
().
getUuid
()))
// clear accession reference
.
forEach
(
ref
->
{
updates
.
incrementAndGet
();
ref
.
setAccession
(
null
);
});
});
datasetRepository
.
save
(
datasets
);
return
updates
.
get
();
}
/**
* {@inheritDoc}
...
...
src/main/java/org/genesys2/server/model/genesys/AccessionData.java
View file @
ebb86823
...
...
@@ -501,23 +501,9 @@ public abstract class AccessionData extends AuditedVersionedModel implements IdU
public
String
getInstCode
()
{
return
this
.
instituteCode
;
}
// FIXME This seems a bit of a hack
public
boolean
getSgsv
()
{
return
this
.
duplSiteStr
!=
null
&&
this
.
duplSiteStr
.
contains
(
"NOR051"
);
}
// TODO Check if needed
public
AccessionRef
toAccessionRef
(){
AccessionRef
res
=
new
AccessionRef
();
res
.
setInstCode
(
getInstCode
());
res
.
setGenus
(
getGenus
());
res
.
setDoi
(
getDoi
());
res
.
setAcceNumb
(
getAccessionNumber
());
res
.
setSpecies
(
getTaxonomy
().
getSpecies
());
res
.
setAccession
((
Accession
)
this
);
return
res
;
}
}
src/main/java/org/genesys2/server/model/genesys/AccessionRef.java
View file @
ebb86823
...
...
@@ -68,6 +68,23 @@ public class AccessionRef implements AccessionIdentifier3, Serializable {
@JsonView
({
JsonViews
.
Public
.
class
})
private
Accession
accession
;
public
AccessionRef
()
{
}
public
AccessionRef
(
Accession
accession
)
{
this
.
instCode
=
accession
.
getInstitute
().
getCode
();
this
.
acceNumb
=
accession
.
getAccessionNumber
();
this
.
genus
=
accession
.
getTaxonomy
().
getGenus
();
this
.
doi
=
accession
.
getDoi
();
this
.
accession
=
accession
;
}
public
AccessionRef
(
String
instCode
,
String
acceNumb
,
String
genus
,
String
doi
)
{
this
.
instCode
=
instCode
;
this
.
acceNumb
=
acceNumb
;
this
.
genus
=
genus
;
this
.
doi
=
doi
;
}
/**
* Gets the doi.
...
...
@@ -271,7 +288,7 @@ public class AccessionRef implements AccessionIdentifier3, Serializable {
}
return
true
;
}
@Override
public
String
toString
()
{
return
"AccessionRef "
+
instCode
+
" "
+
acceNumb
+
" "
+
genus
;
...
...
src/main/java/org/genesys2/server/model/impl/Subset.java
View file @
ebb86823
...
...
@@ -49,7 +49,6 @@ import org.springframework.data.elasticsearch.annotations.FieldType;
import
com.fasterxml.jackson.annotation.JsonView
;
// TODO: Auto-generated Javadoc
/**
* The Class Subset.
*/
...
...
@@ -99,7 +98,7 @@ public class Subset extends UuidModel implements AclAwareModel, SelfCleaning {
indexes
=
{
@Index
(
columnList
=
"subsetId, instCode, acceNumb"
),
@Index
(
columnList
=
"subsetId, genus"
)
})
@Field
(
type
=
FieldType
.
Object
)
@JsonView
({
JsonViews
.
Public
.
class
})
private
Lis
t
<
AccessionRef
>
accessionRefs
;
private
Se
t
<
AccessionRef
>
accessionRefs
;
/** The accession count. */
@Column
(
name
=
"accession_count"
,
nullable
=
false
)
...
...
@@ -276,7 +275,7 @@ public class Subset extends UuidModel implements AclAwareModel, SelfCleaning {
*
* @return the accessionRefs
*/
public
Lis
t
<
AccessionRef
>
getAccessionRefs
()
{
public
Se
t
<
AccessionRef
>
getAccessionRefs
()
{
return
accessionRefs
;
}
...
...
@@ -285,7 +284,7 @@ public class Subset extends UuidModel implements AclAwareModel, SelfCleaning {
*
* @param accessionRefs the new accessionRefs
*/
public
void
setAccessionRefs
(
Lis
t
<
AccessionRef
>
accessions
)
{
public
void
setAccessionRefs
(
Se
t
<
AccessionRef
>
accessions
)
{
this
.
accessionRefs
=
accessions
;
}
...
...
src/main/java/org/genesys2/server/persistence/AccessionRepositoryCustom.java
View file @
ebb86823
...
...
@@ -33,6 +33,8 @@ public interface AccessionRepositoryCustom {
List
<
AccessionData
>
findActiveAndHistoric
(
Collection
<
UUID
>
accessionUuids
);
List
<
Accession
>
find
(
Collection
<
UUID
>
accessionUuids
);
List
<
Accession
>
find
(
List
<
Accession
>
accessions
);
List
<
Accession
>
findById
(
List
<?
extends
AccessionIdentifier3
>
identifiers
);
...
...
src/main/java/org/genesys2/server/persistence/AccessionRepositoryCustomImpl.java
View file @
ebb86823
...
...
@@ -45,6 +45,7 @@ import org.genesys2.server.service.impl.NonUniqueAccessionException;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.dao.IncorrectResultSizeDataAccessException
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.jpa.repository.support.Querydsl
;
...
...
@@ -54,6 +55,8 @@ import org.springframework.transaction.annotation.Transactional;
import
com.querydsl.core.types.dsl.PathBuilder
;
import
com.querydsl.core.types.dsl.PathBuilderFactory
;
import
com.querydsl.jpa.JPQLQuery
;
import
com.querydsl.jpa.impl.JPAQuery
;
import
com.querydsl.jpa.impl.JPAQueryFactory
;
@Repository
@Transactional
(
readOnly
=
true
)
...
...
@@ -61,6 +64,9 @@ public class AccessionRepositoryCustomImpl implements AccessionRepositoryCustom,
public
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
AccessionRepositoryCustomImpl
.
class
);
private
static
final
Predicate
[]
EMPTY_PREDICATE_ARRAY
=
new
Predicate
[]
{};
@Autowired
private
JPAQueryFactory
jpaQueryFactory
;
@PersistenceContext
private
EntityManager
em
;
...
...
@@ -265,6 +271,15 @@ public class AccessionRepositoryCustomImpl implements AccessionRepositoryCustom,
return
activeAndHistoric
;
}
@Override
public
List
<
Accession
>
find
(
Collection
<
UUID
>
accessionUuids
)
{
if
(
accessionUuids
.
isEmpty
())
{
return
Collections
.
emptyList
();
}
JPAQuery
<
Accession
>
query
=
jpaQueryFactory
.
selectFrom
(
QAccession
.
accession
).
distinct
().
where
(
QAccession
.
accession
.
accessionId
.
uuid
.
in
(
accessionUuids
));
return
query
.
fetch
();
}
@Override
public
List
<
Accession
>
findAll
(
AccessionFilter
filter
,
Pageable
page
)
{
...
...
src/main/java/org/genesys2/server/service/SubsetService.java
View file @
ebb86823
...
...
@@ -16,13 +16,13 @@
package
org.genesys2.server.service
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.UUID
;
import
org.genesys.catalog.exceptions.NotFoundElement
;
import
org.genesys2.server.model.genesys.Accession
;
import
org.genesys2.server.model.genesys.AccessionRef
;
import
org.genesys2.server.model.impl.FaoInstitute
;
import
org.genesys2.server.model.impl.Subset
;
import
org.genesys2.server.model.impl.SubsetCreator
;
...
...
@@ -242,4 +242,24 @@ public interface SubsetService {
List
<
SubsetCreator
>
autocompleteCreators
(
String
text
);
/**
* Rematch subset accessions across all Subsets.
*/
void
rematchSubsetAccessions
();
/**
* Rematch subset accessions for a Subset
*
* @param subset the subset
* @return the subset
*/
Subset
rematchSubsetAccessions
(
Subset
subset
);
/**
* Clear accession references across all Subsets for specified accessions.
*
* @param accessions the accessions
* @return the int
*/
int
clearAccessionRefs
(
Collection
<
Accession
>
accessions
);
}
src/main/java/org/genesys2/server/service/impl/SubsetServiceImpl.java
View file @
ebb86823
...
...
@@ -16,13 +16,19 @@
package
org.genesys2.server.service.impl
;
import
static
org
.
genesys2
.
server
.
model
.
impl
.
QSubsetCreator
.
subsetCreator
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.UUID
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.stream.Collectors
;
import
com.querydsl.core.types.Predicate
;
import
javax.persistence.EntityManager
;
import
javax.persistence.PersistenceContext
;
import
org.apache.commons.lang3.StringUtils
;
import
org.genesys.catalog.exceptions.InvalidApiUsageException
;
...
...
@@ -49,19 +55,20 @@ import org.slf4j.LoggerFactory;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.dao.ConcurrencyFailureException
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.PageRequest
;
import
org.springframework.data.domain.PageImpl
;
import
org.springframework.data.domain.PageRequest
;
import
org.springframework.data.domain.Pageable
;
import
org.springframework.data.domain.Sort
;
import
org.springframework.security.access.prepost.PostAuthorize
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.security.acls.domain.BasePermission
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Isolation
;
import
org.springframework.transaction.annotation.Propagation
;
import
org.springframework.transaction.annotation.Transactional
;
import
com.querydsl.core.BooleanBuilder
;
import
static
org
.
genesys2
.
server
.
model
.
impl
.
QSubsetCreator
.
subsetCreator
;
import
com.querydsl.core.types.Predicate
;
/**
* The Class SubsetServiceImpl.
...
...
@@ -145,7 +152,7 @@ public class SubsetServiceImpl implements SubsetService {
* @param target the target
* @param list the subset accessions
*/
private
void
copyAccessions
(
final
Subset
target
,
final
Lis
t
<
AccessionRef
>
list
)
{
private
void
copyAccessions
(
final
Subset
target
,
final
Se
t
<
AccessionRef
>
list
)
{
if
((
list
==
null
)
||
(
list
.
size
()
==
0
))
{
if
(
target
.
getAccessionRefs
()
!=
null
)
target
.
getAccessionRefs
().
clear
();
...
...
@@ -154,11 +161,11 @@ public class SubsetServiceImpl implements SubsetService {
if
(
target
.
getAccessionRefs
()
!=
null
&&
!
target
.
getAccessionRefs
().
isEmpty
())
{
target
.
getAccessionRefs
().
clear
();
target
.
getAccessionRefs
().
addAll
(
list
.
stream
().
distinct
().
collect
(
Collectors
.
toList
()));
}
else
{
target
.
setAccessionRefs
(
list
.
stream
().
distinct
().
collect
(
Collectors
.
toList
()
));
target
.
setAccessionRefs
(
new
HashSet
<>(
));
}
target
.
getAccessionRefs
().
addAll
(
list
);
}
/**
...
...
@@ -270,10 +277,10 @@ public class SubsetServiceImpl implements SubsetService {
*/
@Override
@Transactional
@PreAuthorize
(
"hasRole('ADMINISTRATOR') or hasPermission(#subset, 'WRITE')"
)
public
Subset
delete
(
final
Subset
subset
)
{
@PreAuthorize
(
"hasRole('ADMINISTRATOR') or hasPermission(#input, 'DELETE')"
)
public
Subset
delete
(
final
Subset
input
)
{
final
Subset
subset
=
loadSubset
(
input
);
subsetRepository
.
delete
(
subset
);
subset
.
setId
(
null
);
return
subset
;
}
...
...
@@ -293,7 +300,8 @@ public class SubsetServiceImpl implements SubsetService {
final
Set
<
UUID
>
uuidsToRemove
=
accessions
.
stream
().
map
(
AccessionData:
:
getUuid
).
collect
(
Collectors
.
toSet
());
// Keep accessions that are not in the list
subset
.
setAccessionRefs
(
subset
.
getAccessionRefs
().
stream
().
filter
(
accessionId
->
!
uuidsToRemove
.
contains
(
accessionId
.
getAccession
().
getUuid
())).
collect
(
Collectors
.
toList
()));
subset
.
setAccessionRefs
(
subset
.
getAccessionRefs
().
stream
().
filter
(
accessionId
->
!
uuidsToRemove
.
contains
(
accessionId
.
getAccession
().
getUuid
())).
collect
(
Collectors
.
toSet
()));
subset
.
setState
(
PublishState
.
DRAFT
);
...
...
@@ -310,15 +318,15 @@ public class SubsetServiceImpl implements SubsetService {
LOG
.
info
(
"Add accessions to Subset. Input accessions {}"
,
input
);
final
Subset
subset
=
loadSubset
(
input
);
final
List
<
Accession
Data
>
accessions
=
accessionRepository
.
findActiveAndHistoric
(
accessionsUuids
);
final
List
<
Accession
>
accessions
=
accessionRepository
.
find
(
accessionsUuids
);
final
Set
<
UUID
>
currentAccessions
=
subset
.
getAccessionRefs
().
stream
().
map
(
AccessionRef:
:
getAccession
).
map
(
Accession:
:
getUuid
).
collect
(
Collectors
.
toSet
());
for
(
Accession
Data
accession
:
accessions
)
{
for
(
Accession
accession
:
accessions
)
{
if
(
currentAccessions
.
contains
(
accession
.
getUuid
()))
{
LOG
.
warn
(
"Current Subset already contains accession, ignoring"
);
}
else
{
subset
.
getAccessionRefs
().
add
(
accession
.
toAccessionRef
(
));
subset
.
getAccessionRefs
().
add
(
new
AccessionRef
(
accession
));
currentAccessions
.
add
(
accession
.
getUuid
());
}
}
...
...
@@ -498,11 +506,81 @@ public class SubsetServiceImpl implements SubsetService {
target
.
setRole
(
source
.
getRole
());
}
@Override
public
List
<
SubsetCreator
>
autocompleteCreators
(
String
text
)
{
final
HashSet
<
Long
>
ids
=
new
HashSet
<>(
securityUtils
.
listObjectIdentityIdsForCurrentUser
(
Subset
.
class
,
BasePermission
.
WRITE
));
final
Predicate
predicate
=
subsetCreator
.
subset
.
id
.
in
(
ids
).
and
(
subsetCreator
.
fullName
.
startsWithIgnoreCase
(
text
).
or
(
subsetCreator
.
institutionalAffiliation
.
startsWithIgnoreCase
(
text
)));
final
Predicate
predicate
=
subsetCreator
.
subset
.
id
.
in
(
ids
).
and
(
subsetCreator
.
fullName
.
startsWithIgnoreCase
(
text
).
or
(
subsetCreator
.
institutionalAffiliation
.
startsWithIgnoreCase
(
text
)));
return
subsetCreatorRepository
.
findAll
(
predicate
,
new
PageRequest
(
0
,
20
,
new
Sort
(
"fullName"
))).
getContent
();
}
@Override
@Transactional
(
readOnly
=
false
)
@PreAuthorize
(
"hasRole('ADMINISTRATOR')"
)
public
void
rematchSubsetAccessions
()
{
subsetRepository
.
findAll
().
forEach
(
subset
->
{
rematchSubsetAccessions
(
subset
);
});
}
@Override
@Transactional
(
readOnly
=
false
)
@PreAuthorize
(
"hasRole('ADMINISTRATOR') or hasPermission(#subset, 'write')"
)
public
Subset
rematchSubsetAccessions
(
Subset
subset
)
{
subset
=
subsetRepository
.
getByUuid
(
subset
.
getUuid
());
LOG
.
warn
(
"Linking {} accessions with subset {}"
,
subset
.
getAccessionCount
(),
subset
.
getId
());
subset
.
setAccessionRefs
(
lookupMatchingAccessions
(
subset
.
getAccessionRefs
()));
return
subsetRepository
.
save
(
subset
);
}
/**
* Looking for matching Accession and then sets that to AccessionRef
*
* @param accessionRefs the accessionRefs
*
* @return accessionRefs with matching accessions from Genesys
*/
private
Set
<
AccessionRef
>
lookupMatchingAccessions
(
final
Set
<
AccessionRef
>
accessionRefs
)
{
List
<
AccessionRef
>
list
=
new
ArrayList
<>(
accessionRefs
);
List
<
Accession
>
foundAccessions
=
accessionRepository
.
findById
(
list
);
LOG
.
info
(
"Found {} matches for {} identifiers"
,
foundAccessions
.
size
(),
accessionRefs
.
size
());
accessionRefs
.
forEach
(
ref
->
{
Accession
foundAccession
=
foundAccessions
.
stream
().
filter
(
a
->
{
return
StringUtils
.
equalsIgnoreCase
(
a
.
getInstCode
(),
ref
.
getInstCode
())
&&
(
// when DOI provided
(
ref
.
getDoi
()
!=
null
&&
a
.
getDoi
()
!=
null
&&
StringUtils
.
equals
(
a
.
getDoi
(),
ref
.
getDoi
()))
// OR when without DOI
||
(
StringUtils
.
equalsIgnoreCase
(
a
.
getAccessionNumber
(),
ref
.
getAcceNumb
())
&&
StringUtils
.
equalsIgnoreCase
(
a
.
getGenus
(),
ref
.
getGenus
())));
}).
findFirst
().
orElse
(
null
);
ref
.
setAccession
(
foundAccession
);
if
(
foundAccession
==
null
)
{
LOG
.
debug
(
"No match for {}"
,
ref
);
}
});
return
accessionRefs
;
}
@Override
@Transactional
(
readOnly
=
false
,
propagation
=
Propagation
.
REQUIRED
,
isolation
=
Isolation
.
READ_UNCOMMITTED
)
public
int
clearAccessionRefs
(
Collection
<
Accession
>
accessions
)
{
Set
<
UUID
>
uuids
=
accessions
.
stream
().
map
(
a
->
a
.
getUuid
()).
collect
(
Collectors
.
toSet
());
final
Iterable
<
Subset
>
datasets
=
subsetRepository
.
findAll
(
QSubset
.
subset
.
accessionRefs
.
any
().
accession
.
in
(
accessions
));
AtomicInteger
updates
=
new
AtomicInteger
(
0
);
datasets
.
forEach
(
subset
->
{
subset
.
getAccessionRefs
().
stream
()
// filter for matching accessions
.
filter
(
ref
->
ref
.
getAccession
()
!=
null
&&
uuids
.
contains
(
ref
.
getAccession
().
getUuid
()))
// clear accession reference
.
forEach
(
ref
->
{
updates
.
incrementAndGet
();