Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import org.maurodata.security.AccessControlService
import org.maurodata.service.core.AdministeredItemService
import org.maurodata.service.path.PathService
import org.maurodata.service.plugin.PluginService
import org.maurodata.util.PathStringUtils
import org.maurodata.utils.importer.ImporterUtils

@CompileStatic
Expand Down Expand Up @@ -136,7 +135,7 @@ class DataflowService extends AdministeredItemService {

protected List<DataClass> getImportDataClass(List<DataClass> dataClasses, DataModel model) {
return dataClasses.collect {dC ->
String resourceLabel = PathStringUtils.getItemSubPath(dC.pathPrefix, dC.path.pathString)
String resourceLabel = dC.path.findLastPathNodeByPrefix(dC.pathPrefix).identifier
DataClass importDataClass = findImportDataClassByLabel(resourceLabel, model)
pathRepository.readParentItems(importDataClass) //perhaps not necessary to cal the full path but doing it anyway
importDataClass.updatePath()
Expand Down Expand Up @@ -165,7 +164,7 @@ class DataflowService extends AdministeredItemService {

protected List<DataElement> getImportDataElements(List<DataElement> dataElements, DataModel model) {
return dataElements.collect {dE ->
String resourceLabel = PathStringUtils.getItemSubPath(dE.pathPrefix, dE.path.pathString)
String resourceLabel = dE.path.findLastPathNodeByPrefix(dE.pathPrefix).identifier
List<DataElement> importElementsWithSameLabel = model.dataElements.findAll {
it.label == resourceLabel
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,8 @@ import org.maurodata.domain.security.Role
import org.maurodata.persistence.cache.AdministeredItemCacheableRepository
import org.maurodata.persistence.model.PathRepository
import org.maurodata.security.AccessControlService
import org.maurodata.domain.model.Path

import static org.maurodata.util.PathStringUtils.getCOLON
import static org.maurodata.util.PathStringUtils.getDISCARD_AFTER_VERSION
import static org.maurodata.util.PathStringUtils.getItemSubPath
import static org.maurodata.util.PathStringUtils.getREMOVE_VERSION_DELIM
import static org.maurodata.util.PathStringUtils.getVersionFromPath
import static org.maurodata.util.PathStringUtils.lastSubPath
import static org.maurodata.util.PathStringUtils.splitBy

@CompileStatic
@Slf4j
Expand All @@ -34,7 +28,8 @@ class PathService implements AdministeredItemReader {
@Inject
AccessControlService accessControlService

AdministeredItem getResourceByPath(String domainType, String path) {
AdministeredItem getResourceByPath(String domainType, String pathString) {
Path path = new Path(pathString)
AdministeredItem item = findResourceByPath(domainType, path)
ErrorHandler.handleErrorOnNullObject(HttpStatus.NOT_FOUND, item, "Item with DomainType $domainType not found with path: $path")

Expand All @@ -44,20 +39,22 @@ class PathService implements AdministeredItemReader {
}


AdministeredItem getResourceByPathFromResource(String domainType, UUID domainId, String path){
AdministeredItem getResourceByPathFromResource(String domainType, UUID domainId, String pathString){
AdministeredItem fromModel = findAdministeredItem(domainType, domainId)
ErrorHandler.handleErrorOnNullObject(HttpStatus.NOT_FOUND, fromModel, "Model $domainType, $domainId not found")

accessControlService.checkRole(Role.READER, fromModel)
updateDerivedProperties(fromModel)

//verify model path in the input path
if (!path.contains(fromModel.path.pathString)) {
ErrorHandler.handleError(HttpStatus.NOT_FOUND, "Path $path does not belong to $domainType, $domainId")
if (!pathString.contains(fromModel.path.pathString)) {
ErrorHandler.handleError(HttpStatus.NOT_FOUND, "Path $pathString does not belong to $domainType, $domainId")
}
Tuple2<String, String> itemDomainTypeAndPath = getItemDomainTypeAndPath(path)
AdministeredItem administeredItem = findResourceByPath(itemDomainTypeAndPath.first, path)
ErrorHandler.handleErrorOnNullObject(HttpStatus.NOT_FOUND, administeredItem, "Item with $itemDomainTypeAndPath.first and label $itemDomainTypeAndPath.v2 not found")
Path path = new Path(pathString)
Path.PathNode lastPathNode = path.lastPathNode()
String itemDomainType = getDomainTypeFromPathPrefix(lastPathNode.prefix)
AdministeredItem administeredItem = findResourceByPath(itemDomainType, path)
ErrorHandler.handleErrorOnNullObject(HttpStatus.NOT_FOUND, administeredItem, "Item with ${lastPathNode.prefix} and label ${lastPathNode.identifier} not found")
accessControlService.checkRole(Role.READER, administeredItem)
updateDerivedProperties(administeredItem)
administeredItem
Expand All @@ -77,33 +74,13 @@ class PathService implements AdministeredItemReader {
* @return the admin item, given the full path including versioning
*/

protected AdministeredItem findResourceByPath(String domainType, String path) {
protected AdministeredItem findResourceByPath(String domainType, Path path) {
String pathPrefix = getPathPrefixForDomainType(domainType)
String domainPath = getItemSubPath(pathPrefix, path)
String versionString = getVersionFromPath(path)
String domainPath = path.findLastPathNodeByPrefix(pathPrefix).identifier
String versionString = path.modelIdentifier
return findItemForPath(domainType, domainPath, versionString, path)
}


/**
*
* @param path fullPath
* @return the last path domainType and label/subPath
*/
protected Tuple2<String,String> getItemDomainTypeAndPath(String path) {
String itemPath = lastSubPath(path)
//extract the item domain type from given input path
String[] itemParts = splitBy(itemPath, COLON)
if (itemParts.size() != 2){
ErrorHandler.handleError(HttpStatus.UNPROCESSABLE_ENTITY, "bad path $path")
}
String itemDomainType = getDomainTypeFromPathPrefix(itemParts[0])
String subPathOnly = itemParts[1].find(DISCARD_AFTER_VERSION) ?: itemParts[1]

String itemSubPath = subPathOnly.replaceAll(REMOVE_VERSION_DELIM, '')
new Tuple2(itemDomainType, itemSubPath)
}

protected String getPathPrefixForDomainType(String domainType) {
AdministeredItemCacheableRepository repo = repositoryService.administeredItemCacheableRepositories.find {
it.handles(domainType)
Expand All @@ -129,24 +106,24 @@ class PathService implements AdministeredItemReader {
item
}

protected AdministeredItem findItemForPath(String domainType, String domainPath, String versionString, String fullPath) {
protected AdministeredItem findItemForPath(String domainType, String domainPath, String versionString, Path path) {
AdministeredItemCacheableRepository repository = getAdministeredItemRepository(domainType)
List<AdministeredItem> items = repository.findAllByLabel(domainPath)
List<AdministeredItem> items = repository.findAllByLabel(domainPath) as List<AdministeredItem>
if (items.isEmpty()) {
null
return null
}
AdministeredItem item
if (items.size() == 1) {
item = items[0] as AdministeredItem
} else {
if (!versionString) {
log.warn("No version found in fullpath: $fullPath; returning 1st item")
items.first()
log.warn("No version found in path: ${path.toString()}; returning 1st item")
return items.first()
}
item = (items as List<AdministeredItem>).find {
pathRepository.readParentItems(it)
it.updatePath()
it.path?.pathString?.contains(versionString)
it.path?.modelIdentifier == versionString
}
}
item
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class PathControllerIntegrationSpec extends CommonDataSpec {

void 'test getResource by path -path not found -shouldThrowException'() {
when:
pathApi.getResourceByPath('datamodel', 'not known label')
pathApi.getResourceByPath('datamodel', 'dm:not known label')

then:
HttpStatusException exception = thrown()
Expand All @@ -68,14 +68,14 @@ class PathControllerIntegrationSpec extends CommonDataSpec {

void 'test getResource by path -unknown domainType -shouldThrowException'() {
when:
pathApi.getResourceByPath('whatisthis', EXPECTED_LABEL)
pathApi.getResourceByPath('whatisthis', "dm:${EXPECTED_LABEL}" )

then:
HttpStatusException exception = thrown()
exception.status == HttpStatus.NOT_FOUND
}

void 'test getResource by Path from Resource -should find resource'() {
void 'test getResource by Path from Resource1 -should find resource'() {
DataModel dataModel = dataModelApi.create(folderId, dataModelPayload('datamodel label '))
DataType dataType = dataTypeApi.create(dataModel.id, dataTypesPayload('label for datatype', DataType.DataTypeKind.ENUMERATION_TYPE))
DataClass dataClass = dataClassApi.create(dataModel.id, dataClassPayload('label for dataclass'))
Expand Down Expand Up @@ -124,7 +124,7 @@ class PathControllerIntegrationSpec extends CommonDataSpec {


//todo: fixme the version info is not part of the pathsstring for modelitems so unable to match exact version
void 'test getResource by Path from Resource -should find resource'() {
void 'test getResource by Path from Resource2 -should find resource'() {
DataModel dataModel = dataModelApi.create(folderId, dataModelPayload('datamodel label '))
DataClass dataClass = dataClassApi.create(dataModel.id, dataClassPayload('label for dataclass'))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class Path {
}

void updatePathString() {
final String modelIdentifier = getModelIdentifier()
nodes.each {PathNode pathNode -> pathNode.modelIdentifier = null}
setModelIdentifier(modelIdentifier)
pathString = nodes.collect {it.toString()}.join('|')
}

Expand Down Expand Up @@ -144,6 +147,42 @@ class Path {
trimmed.pathString
}

@Transient
PathNode findLastPathNodeByPrefix(final String prefix) {
for (int p = nodes.size() - 1; p >= 0; p--) {
final PathNode pathNode = nodes.get(p)
if (pathNode.prefix == prefix) {return pathNode}
}
return null
}

@Transient
PathNode lastPathNode() {
if (nodes.isEmpty()) {return null}
return nodes.get(nodes.size() - 1)
}

@Transient
String getModelIdentifier() {
for (int p = 0, n = nodes.size(); p < n; p++) {
final PathNode pathNode = nodes.get(p)
if (!PathNode.canHaveModelIdentifier.contains(pathNode.prefix)) {continue}
if (pathNode.modelIdentifier) {return pathNode.modelIdentifier}
}
return null
}

void setModelIdentifier(final String modelIdentifier) {
nodes.each {PathNode pathNode -> pathNode.modelIdentifier = null}
for (int p = 0, n = nodes.size(); p < n; p++) {
final PathNode pathNode = nodes.get(p)
if (!PathNode.canHaveModelIdentifier.contains(pathNode.prefix)) {continue}
pathNode.modelIdentifier = modelIdentifier
break
}
pathString = nodes.collect {it.toString()}.join('|')
}

static class PathNode {
String prefix
String identifier
Expand All @@ -161,6 +200,8 @@ class Path {
value
}

static List<String> canHaveModelIdentifier = ['dm','vf','csc','cs','te']

static PathNode from(String str) {
Pattern nodePattern = ~/^(?<prefix>\w\w\w?):(?<identifier>[^@$]*)(\$(?<modelIdentifier>[^@]*))?(@(?<attribute>.*))?$/
Matcher matcher = str =~ nodePattern
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
package org.maurodata.test.domain.util
package org.maurodata.test.domain.model

import org.maurodata.domain.model.Path

import io.micronaut.test.extensions.spock.annotation.MicronautTest
import org.maurodata.util.PathStringUtils
import spock.lang.Specification
import spock.lang.Unroll

@MicronautTest
class PathStringUtilsTest extends Specification {
class PathMethodsTest extends Specification {

@Unroll
void 'test getItemSubPath, for #pathPrefix, #fullPath'() {
void 'test findLastPathNodeByPrefix, for #pathPrefix, #fullPath'() {
when:
String subPath = PathStringUtils.getItemSubPath(pathPrefix, fullPath)
Path.PathNode pathNode = new Path(fullPath).findLastPathNodeByPrefix(pathPrefix)

then:
subPath
subPath == expectedSubPath
pathNode
pathNode.identifier == expectedSubPath

where:
pathPrefix | fullPath | expectedSubPath
Expand All @@ -30,19 +31,20 @@ class PathStringUtilsTest extends Specification {
}

@Unroll
void 'test getVersionFromPath for #fullPath'() {
void 'test modelIdentifier for #fullPath'() {
when:
String version = PathStringUtils.getVersionFromPath(fullPath)
String modelIdentifier = new Path(fullPath).modelIdentifier

then:
version == expectedVersion
modelIdentifier == expectedVersion

where:
fullPath | expectedVersion
"fo:soluta eum architecto|dm:modi unde est\$matrix|dc:est quasi vel|de:new data element label\$2.0.0" | "2.0.0"
"dm:BC_Bloods\$2.0.0" | "2.0.0"
"fo:soluta eum architecto" | null
"fo:soluta eum architecto|te:Dewey Decimal Classification v22\$main" | "main"
fullPath | expectedVersion
'fo:soluta eum architecto|dm:modi unde est$matrix|dc:est quasi vel|de:new data element label$2.0.0' | "matrix"
'dm:BC_Bloods$2.0.0' | "2.0.0"
'fo:soluta eum architecto' | null
'fo:soluta eum architecto|te:Dewey Decimal Classification v22$main' | "main"
'fo:soluta eum architecto|vf:versionio de folder$main|te:Dewey Decimal Classification v22$main' | "main"
}

}
Loading