com.netgrif.application.engine.petrinet.service.UriService Maven / Gradle / Ivy
package com.netgrif.application.engine.petrinet.service;
import com.netgrif.application.engine.configuration.properties.UriProperties;
import com.netgrif.application.engine.petrinet.domain.UriContentType;
import com.netgrif.application.engine.petrinet.domain.UriNode;
import com.netgrif.application.engine.petrinet.domain.repository.UriNodeRepository;
import com.netgrif.application.engine.petrinet.service.interfaces.IUriService;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
/**
* Service for managing UriNode objects
*/
@Service
public class UriService implements IUriService {
private static final int FIRST_LEVEL = 0;
private final UriNodeRepository uriNodeRepository;
private final UriProperties uriProperties;
public UriService(UriNodeRepository uriNodeRepository, UriProperties uriProperties) {
this.uriNodeRepository = uriNodeRepository;
this.uriProperties = uriProperties;
}
/**
* Saves UriNode object to database
*
* @param uriNode to be saved
*/
@Override
public UriNode save(UriNode uriNode) {
return uriNodeRepository.save(uriNode);
}
/**
* Retrieves all UriNode based on parent ID
*
* @param parentId ID of parent UriNode
* @return list of UriNode
*/
@Override
public List findAllByParent(String parentId) {
return uriNodeRepository.findAllByParentId(parentId);
}
/**
* Retrieves all UriNode that are root nodes
*
* @return list of UriNode
*/
@Override
public UriNode getRoot() {
List nodes = uriNodeRepository.findAllByLevel(FIRST_LEVEL);
if (nodes.size() != 1) {
throw new IllegalStateException("Exactly one root uri node must exist!");
}
return nodes.get(0);
}
/**
* Retrieves all UriNode based on level
*
* @param level of UriNodes
* @return list of UriNodes
*/
@Override
public List findByLevel(int level) {
return uriNodeRepository.findAllByLevel(level);
}
/**
* Retrieves UriNode based on ID
*
* @param id ID of UriNode
* @return UriNode
*/
@Override
public UriNode findById(String id) {
Optional navNodeOptional = uriNodeRepository.findById(id);
if (navNodeOptional.isEmpty()) {
throw new IllegalArgumentException("Could not find NavNode with id [" + id + "]");
}
return navNodeOptional.get();
}
/**
* Retrieves UriNode based on uri
*
* @param uri ID of UriNode
* @return UriNode
*/
@Override
public UriNode findByUri(String uri) {
return uriNodeRepository.findByUriPath(uri);
}
/**
* Collects direct relatives (parent and children) of input UriNode and returns filled object
*
* @param uriNode to be filled with relatives
* @return filled UriNode
*/
@Override
public UriNode populateDirectRelatives(UriNode uriNode) {
if (uriNode == null) {
return null;
}
if (uriNode.getLevel() != FIRST_LEVEL) {
UriNode parent = findById(uriNode.getParentId());
uriNode.setParent(parent);
}
Set children = StreamSupport.stream(uriNodeRepository.findAllById(uriNode.getChildrenId()).spliterator(), false).collect(Collectors.toSet());
uriNode.setChildren(children);
return uriNode;
}
/**
* Moves UriNode to other destination
*
* @param uri to be moved
* @param destUri the destination URI
* @return result UriNode object
*/
@Override
public UriNode move(String uri, String destUri) {
UriNode uriNode = findByUri(uri);
return move(uriNode, destUri);
}
/**
* Moves UriNode to other destination
*
* @param node to be moved
* @param destUri the destination URI
* @return result UriNode object
*/
@Override
public UriNode move(UriNode node, String destUri) {
if (isPathCycle(node.getUriPath(), destUri)) {
throw new IllegalArgumentException("Uri node with path " + node.getUriPath() + " cannot be moved to path " + destUri + " due to cyclic paths");
}
UriNode newParent = getOrCreate(destUri, null);
UriNode oldParent = findById(node.getParentId());
if (destUri.indexOf(uriProperties.getSeparator()) != 0) {
destUri = uriProperties.getSeparator() + destUri;
}
String oldNodePath = node.getUriPath();
String newNodePath = destUri + (destUri.equals(uriProperties.getSeparator()) ? "" : uriProperties.getSeparator()) + node.getName();
node.setUriPath(newNodePath);
node.setParentId(newParent.getStringId());
node.setLevel(newParent.getLevel() + 1);
oldParent.getChildrenId().remove(node.getStringId());
newParent.getChildrenId().add(node.getStringId());
List childrenToSave = new ArrayList<>();
if (!node.getChildrenId().isEmpty()) {
node = populateDirectRelatives(node);
childrenToSave.addAll(moveChildrenRecursive(oldNodePath, newNodePath, node.getChildren()));
}
uriNodeRepository.saveAll(List.of(oldParent, newParent, node));
uriNodeRepository.saveAll(childrenToSave);
return node;
}
private boolean isPathCycle(String picked, String dest) {
return dest.startsWith(picked);
}
private List moveChildrenRecursive(String oldParentPath, String newParentPath, Set nodes) {
List updated = new ArrayList<>();
if (nodes == null || nodes.isEmpty()) {
return new ArrayList<>();
}
for (UriNode node : nodes) {
String oldPath = node.getUriPath();
String diff = calcPathDifference(oldPath, oldParentPath);
String newPath = newParentPath + diff;
node.setUriPath(newPath);
updated.add(node);
node = populateDirectRelatives(node);
updated.addAll(moveChildrenRecursive(oldPath, newPath, node.getChildren()));
}
return updated;
}
private String calcPathDifference(String path1, String path2) {
return StringUtils.difference(path2, path1);
}
/**
* Creates new UriNode from URI path, or retrieves existing one
*
* @param uri to be used for creating UriNode
* @param contentType to decide the content type of UriNode
* @return the UriNode that was created or modified /netgrif/process/test/all_data, /netgrif/process
*/
@Override
public UriNode getOrCreate(String uri, UriContentType contentType) {
if (!uri.startsWith(uriProperties.getSeparator())) {
uri = uriProperties.getSeparator() + uri;
}
LinkedList uriNodeList = new LinkedList<>();
String[] uriComponents = uri.split(uriProperties.getSeparator());
if (uriComponents.length == 0) {
uriComponents = new String[]{uriProperties.getSeparator()};
} else {
uriComponents[0] = uriProperties.getSeparator();
}
StringBuilder uriBuilder = new StringBuilder();
int pathLength = uriComponents.length;
UriNode parent = null;
for (int i = 0; i < pathLength; i++) {
uriBuilder.append(uriComponents[i]);
UriNode uriNode = findByUri(uriBuilder.toString());
if (uriNode == null) {
uriNode = new UriNode();
uriNode.setName(uriComponents[i]);
uriNode.setLevel(i);
uriNode.setUriPath(uriBuilder.toString());
uriNode.setParentId(parent != null ? parent.getStringId() : null);
}
if (i == pathLength - 1 && contentType != null) {
uriNode.addContentType(contentType);
}
uriNode = uriNodeRepository.save(uriNode);
if (parent != null) {
parent.getChildrenId().add(uriNode.getStringId());
uriNodeRepository.save(parent);
}
if (i > 0) {
uriBuilder.append(uriProperties.getSeparator());
}
uriNodeList.add(uriNode);
parent = uriNode;
}
return uriNodeList.getLast();
}
/**
* Creates default UriNode
*
* @return the UriNode that was created or modified
*/
@Override
public UriNode createDefault() {
UriNode uriNode = uriNodeRepository.findByUriPath(uriProperties.getSeparator());
if (uriNode == null) {
uriNode = new UriNode();
uriNode.setName(uriProperties.getName());
uriNode.setLevel(FIRST_LEVEL);
uriNode.setUriPath(uriProperties.getSeparator());
uriNode.setParentId(null);
uriNode.addContentType(UriContentType.DEFAULT);
uriNode = uriNodeRepository.save(uriNode);
}
return uriNode;
}
@Override
public String getUriSeparator() {
return uriProperties.getSeparator();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy