use of org.alfresco.rest.api.model.Node in project alfresco-remote-api by Alfresco.
the class NodesImpl method getFolderOrDocument.
@Override
public Node getFolderOrDocument(String nodeId, Parameters parameters) {
String path = parameters.getParameter(PARAM_RELATIVE_PATH);
NodeRef nodeRef = validateOrLookupNode(nodeId, path);
Node node = getFolderOrDocumentFullInfo(nodeRef, null, null, parameters);
return node;
}
use of org.alfresco.rest.api.model.Node in project alfresco-remote-api by Alfresco.
the class NodesImpl method createNode.
@Override
public Node createNode(String parentFolderNodeId, Node nodeInfo, Parameters parameters) {
if (nodeInfo.getNodeRef() != null) {
throw new InvalidArgumentException("Unexpected id when trying to create a new node: " + nodeInfo.getNodeRef().getId());
}
validateAspects(nodeInfo.getAspectNames(), EXCLUDED_NS, EXCLUDED_ASPECTS);
validateProperties(nodeInfo.getProperties(), EXCLUDED_NS, Arrays.asList());
// check that requested parent node exists and it's type is a (sub-)type of folder
NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null);
// node name - mandatory
String nodeName = nodeInfo.getName();
if ((nodeName == null) || nodeName.isEmpty()) {
throw new InvalidArgumentException("Node name is expected: " + parentNodeRef.getId());
}
// node type - check that requested type is a (sub-) type of cm:object
String nodeType = nodeInfo.getNodeType();
if ((nodeType == null) || nodeType.isEmpty()) {
throw new InvalidArgumentException("Node type is expected: " + parentNodeRef.getId() + "," + nodeName);
}
QName nodeTypeQName = createQName(nodeType);
boolean isContent = isSubClass(nodeTypeQName, ContentModel.TYPE_CONTENT);
if (!isContent) {
validateCmObject(nodeTypeQName);
}
/* RA-834: commented-out since not currently applicable for empty file
List<ThumbnailDefinition> thumbnailDefs = null;
String renditionsParam = parameters.getParameter(PARAM_RENDITIONS);
if (renditionsParam != null)
{
if (!isContent)
{
throw new InvalidArgumentException("Renditions ['"+renditionsParam+"'] only apply to content types: "+parentNodeRef.getId()+","+nodeName);
}
thumbnailDefs = getThumbnailDefs(renditionsParam);
}
*/
Map<QName, Serializable> props = new HashMap<>(1);
if (nodeInfo.getProperties() != null) {
// node properties - set any additional properties
props = mapToNodeProperties(nodeInfo.getProperties());
}
// Optionally, lookup by relative path
String relativePath = nodeInfo.getRelativePath();
parentNodeRef = getOrCreatePath(parentNodeRef, relativePath);
// Existing file/folder name handling
boolean autoRename = Boolean.valueOf(parameters.getParameter(PARAM_AUTO_RENAME));
if (autoRename && (isContent || isSubClass(nodeTypeQName, ContentModel.TYPE_FOLDER))) {
NodeRef existingNode = nodeService.getChildByName(parentNodeRef, ContentModel.ASSOC_CONTAINS, nodeName);
if (existingNode != null) {
// File already exists, find a unique name
nodeName = findUniqueName(parentNodeRef, nodeName);
}
}
QName assocTypeQName = ContentModel.ASSOC_CONTAINS;
if ((nodeInfo.getAssociation() != null) && (nodeInfo.getAssociation().getAssocType() != null)) {
assocTypeQName = getAssocType(nodeInfo.getAssociation().getAssocType());
}
Boolean versionMajor = null;
String str = parameters.getParameter(PARAM_VERSION_MAJOR);
if (str != null) {
versionMajor = Boolean.valueOf(str);
}
String versionComment = parameters.getParameter(PARAM_VERSION_COMMENT);
// Create the node
NodeRef nodeRef;
if (isContent) {
// create empty file node - note: currently will be set to default encoding only (UTF-8)
nodeRef = createNewFile(parentNodeRef, nodeName, nodeTypeQName, null, props, assocTypeQName, parameters, versionMajor, versionComment);
} else {
// create non-content node
nodeRef = createNodeImpl(parentNodeRef, nodeName, nodeTypeQName, props, assocTypeQName);
}
addCustomAspects(nodeRef, nodeInfo.getAspectNames(), EXCLUDED_ASPECTS);
processNodePermissions(nodeRef, nodeInfo);
if (nodeInfo.getTargets() != null) {
addTargets(nodeRef.getId(), nodeInfo.getTargets());
}
if (nodeInfo.getSecondaryChildren() != null) {
addChildren(nodeRef.getId(), nodeInfo.getSecondaryChildren());
}
Node newNode = getFolderOrDocument(nodeRef.getId(), parameters);
return newNode;
}
use of org.alfresco.rest.api.model.Node in project alfresco-remote-api by Alfresco.
the class NodesImpl method getFolderOrDocument.
@Override
public Node getFolderOrDocument(final NodeRef nodeRef, NodeRef parentNodeRef, QName nodeTypeQName, List<String> includeParam, Map<String, UserInfo> mapUserInfo) {
if (mapUserInfo == null) {
mapUserInfo = new HashMap<>(2);
}
if (includeParam == null) {
includeParam = Collections.emptyList();
}
Node node;
Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
PathInfo pathInfo = null;
if (includeParam.contains(PARAM_INCLUDE_PATH)) {
ChildAssociationRef archivedParentAssoc = (ChildAssociationRef) properties.get(ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC);
pathInfo = lookupPathInfo(nodeRef, archivedParentAssoc);
}
if (nodeTypeQName == null) {
nodeTypeQName = getNodeType(nodeRef);
}
if (parentNodeRef == null) {
parentNodeRef = getParentNodeRef(nodeRef);
}
Type type = getType(nodeTypeQName, nodeRef);
if (type == null) {
// not direct folder (or file) ...
// might be sub-type of cm:cmobject (or a cm:link pointing to cm:cmobject or possibly even another cm:link)
node = new Node(nodeRef, parentNodeRef, properties, mapUserInfo, sr);
node.setIsFolder(false);
node.setIsFile(false);
} else if (type.equals(Type.DOCUMENT)) {
node = new Document(nodeRef, parentNodeRef, properties, mapUserInfo, sr);
} else if (type.equals(Type.FOLDER)) {
node = new Folder(nodeRef, parentNodeRef, properties, mapUserInfo, sr);
} else {
throw new RuntimeException("Unexpected - should not reach here: " + type);
}
if (includeParam.size() > 0) {
node.setProperties(mapFromNodeProperties(properties, includeParam, mapUserInfo, EXCLUDED_NS, EXCLUDED_PROPS));
}
Set<QName> aspects = null;
if (includeParam.contains(PARAM_INCLUDE_ASPECTNAMES)) {
aspects = nodeService.getAspects(nodeRef);
node.setAspectNames(mapFromNodeAspects(aspects, EXCLUDED_NS, EXCLUDED_ASPECTS));
}
if (includeParam.contains(PARAM_INCLUDE_ISLINK)) {
boolean isLink = isSubClass(nodeTypeQName, ContentModel.TYPE_LINK);
node.setIsLink(isLink);
}
if (includeParam.contains(PARAM_INCLUDE_ISLOCKED)) {
boolean isLocked = isLocked(nodeRef, aspects);
node.setIsLocked(isLocked);
}
if (includeParam.contains(PARAM_INCLUDE_ISFAVORITE)) {
boolean isFavorite = isFavorite(nodeRef);
node.setIsFavorite(isFavorite);
}
if (includeParam.contains(PARAM_INCLUDE_ALLOWABLEOPERATIONS)) {
// note: refactor when requirements change
Map<String, String> mapPermsToOps = new HashMap<>(3);
mapPermsToOps.put(PermissionService.DELETE, OP_DELETE);
mapPermsToOps.put(PermissionService.ADD_CHILDREN, OP_CREATE);
mapPermsToOps.put(PermissionService.WRITE, OP_UPDATE);
mapPermsToOps.put(PermissionService.CHANGE_PERMISSIONS, OP_UPDATE_PERMISSIONS);
List<String> allowableOperations = new ArrayList<>(3);
for (Entry<String, String> kv : mapPermsToOps.entrySet()) {
String perm = kv.getKey();
String op = kv.getValue();
if (perm.equals(PermissionService.ADD_CHILDREN) && Type.DOCUMENT.equals(type)) {
// special case: do not return "create" (as an allowable op) for file/content types - note: 'type' can be null
continue;
} else if (perm.equals(PermissionService.DELETE) && (isSpecialNode(nodeRef, nodeTypeQName))) {
// special case: do not return "delete" (as an allowable op) for specific system nodes
continue;
} else if (permissionService.hasPermission(nodeRef, perm) == AccessStatus.ALLOWED) {
allowableOperations.add(op);
}
}
node.setAllowableOperations((allowableOperations.size() > 0) ? allowableOperations : null);
}
if (includeParam.contains(PARAM_INCLUDE_PERMISSIONS)) {
Boolean inherit = permissionService.getInheritParentPermissions(nodeRef);
List<NodePermissions.NodePermission> inheritedPerms = new ArrayList<>(5);
List<NodePermissions.NodePermission> setDirectlyPerms = new ArrayList<>(5);
Set<String> settablePerms = null;
boolean allowRetrievePermission = true;
try {
for (AccessPermission accessPerm : permissionService.getAllSetPermissions(nodeRef)) {
NodePermissions.NodePermission nodePerm = new NodePermissions.NodePermission(accessPerm.getAuthority(), accessPerm.getPermission(), accessPerm.getAccessStatus().toString());
if (accessPerm.isSetDirectly()) {
setDirectlyPerms.add(nodePerm);
} else {
inheritedPerms.add(nodePerm);
}
}
settablePerms = permissionService.getSettablePermissions(nodeRef);
} catch (AccessDeniedException ade) {
// ignore - ie. denied access to retrieve permissions, eg. non-admin on root (Company Home)
allowRetrievePermission = false;
}
// returned only node info that he's allowed to see
if (allowRetrievePermission) {
NodePermissions nodePerms = new NodePermissions(inherit, inheritedPerms, setDirectlyPerms, settablePerms);
node.setPermissions(nodePerms);
}
}
if (includeParam.contains(PARAM_INCLUDE_ASSOCIATION)) {
// Ugh ... can we optimise this and return the actual assoc directly (via FileFolderService/GetChildrenCQ) ?
ChildAssociationRef parentAssocRef = nodeService.getPrimaryParent(nodeRef);
// note: parentAssocRef.parentRef can be null for -root- node !
if ((parentAssocRef == null) || (parentAssocRef.getParentRef() == null) || (!parentAssocRef.getParentRef().equals(parentNodeRef))) {
List<ChildAssociationRef> parentAssocRefs = nodeService.getParentAssocs(nodeRef);
for (ChildAssociationRef pAssocRef : parentAssocRefs) {
if (pAssocRef.getParentRef().equals(parentNodeRef)) {
// for now, assume same parent/child cannot appear more than once (due to unique name)
parentAssocRef = pAssocRef;
break;
}
}
}
if (parentAssocRef != null) {
QName assocTypeQName = parentAssocRef.getTypeQName();
if ((assocTypeQName != null) && (!EXCLUDED_NS.contains(assocTypeQName.getNamespaceURI()))) {
AssocChild childAssoc = new AssocChild(assocTypeQName.toPrefixString(namespaceService), parentAssocRef.isPrimary());
node.setAssociation(childAssoc);
}
}
}
if (includeParam.contains(PARAM_INCLUDE_DEFINITION)) {
NodeDefinition nodeDefinition = nodeDefinitionMapper.fromTypeDefinition(getTypeDefinition(nodeRef), dictionaryService);
node.setDefinition(nodeDefinition);
}
node.setNodeType(nodeTypeQName.toPrefixString(namespaceService));
node.setPath(pathInfo);
return node;
}
use of org.alfresco.rest.api.model.Node in project alfresco-remote-api by Alfresco.
the class NodesImpl method upload.
@Override
public Node upload(String parentFolderNodeId, FormData formData, Parameters parameters) {
if (formData == null || !formData.getIsMultiPart()) {
throw new InvalidArgumentException("The request content-type is not multipart: " + parentFolderNodeId);
}
NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null);
if (!nodeMatches(parentNodeRef, Collections.singleton(ContentModel.TYPE_FOLDER), null, false)) {
throw new InvalidArgumentException("NodeId of folder is expected: " + parentNodeRef.getId());
}
String fileName = null;
Content content = null;
boolean autoRename = false;
QName nodeTypeQName = ContentModel.TYPE_CONTENT;
// If a fileName clashes for a versionable file
boolean overwrite = false;
Boolean versionMajor = null;
String versionComment = null;
String relativePath = null;
String renditionNames = null;
Map<String, Object> qnameStrProps = new HashMap<>();
Map<QName, Serializable> properties = null;
Map<String, String[]> formDataParameters = formData.getParameters();
for (FormData.FormField field : formData.getFields()) {
switch(field.getName().toLowerCase()) {
case "name":
String str = getStringOrNull(field.getValue());
if ((str != null) && (!str.isEmpty())) {
fileName = str;
}
break;
case "filedata":
if (field.getIsFile()) {
fileName = (fileName != null ? fileName : field.getFilename());
content = field.getContent();
}
break;
case "autorename":
autoRename = Boolean.valueOf(field.getValue());
break;
case "nodetype":
nodeTypeQName = createQName(getStringOrNull(field.getValue()));
if (!isSubClass(nodeTypeQName, ContentModel.TYPE_CONTENT)) {
throw new InvalidArgumentException("Can only upload type of cm:content: " + nodeTypeQName);
}
break;
case "overwrite":
overwrite = Boolean.valueOf(field.getValue());
break;
case "majorversion":
versionMajor = Boolean.valueOf(field.getValue());
break;
case "comment":
versionComment = getStringOrNull(field.getValue());
break;
case "relativepath":
relativePath = getStringOrNull(field.getValue());
break;
case "renditions":
renditionNames = getStringOrNull(field.getValue());
break;
default:
{
final String propName = field.getName();
if (propName.indexOf(QName.NAMESPACE_PREFIX) > -1 && !qnameStrProps.containsKey(propName)) {
String[] fieldValue = formDataParameters.get(propName);
if (fieldValue.length > 1) {
qnameStrProps.put(propName, Arrays.asList(fieldValue));
} else {
qnameStrProps.put(propName, fieldValue[0]);
}
}
}
}
}
// destination, or site + container or updateNodeRef
if ((fileName == null) || fileName.isEmpty() || (content == null)) {
throw new InvalidArgumentException("Required parameters are missing");
}
if (autoRename && overwrite) {
throw new InvalidArgumentException("Both 'overwrite' and 'autoRename' should not be true when uploading a file");
}
// if requested, make (get or create) path
parentNodeRef = getOrCreatePath(parentNodeRef, relativePath);
final QName assocTypeQName = ContentModel.ASSOC_CONTAINS;
final Set<String> renditions = getRequestedRenditions(renditionNames);
validateProperties(qnameStrProps, EXCLUDED_NS, Arrays.asList());
try {
// Map the given properties, if any.
if (qnameStrProps.size() > 0) {
properties = mapToNodeProperties(qnameStrProps);
}
/*
* Existing file handling
*/
NodeRef existingFile = nodeService.getChildByName(parentNodeRef, assocTypeQName, fileName);
if (existingFile != null) {
// File already exists, decide what to do
if (autoRename) {
// attempt to find a unique name
fileName = findUniqueName(parentNodeRef, fileName);
// drop-through !
} else if (overwrite && nodeService.hasAspect(existingFile, ContentModel.ASPECT_VERSIONABLE)) {
// overwrite existing (versionable) file
BasicContentInfo contentInfo = new ContentInfoImpl(content.getMimetype(), content.getEncoding(), -1, null);
return updateExistingFile(parentNodeRef, existingFile, fileName, contentInfo, content.getInputStream(), parameters, versionMajor, versionComment);
} else {
// name clash (and no autoRename or overwrite)
throw new ConstraintViolatedException(fileName + " already exists.");
}
}
// Note: pending REPO-159, we currently auto-enable versioning on new upload (but not when creating empty file)
if (versionMajor == null) {
versionMajor = true;
}
// Create a new file.
NodeRef nodeRef = createNewFile(parentNodeRef, fileName, nodeTypeQName, content, properties, assocTypeQName, parameters, versionMajor, versionComment);
// Create the response
final Node fileNode = getFolderOrDocumentFullInfo(nodeRef, parentNodeRef, nodeTypeQName, parameters);
checkRenditionNames(renditions);
requestRenditions(renditions, fileNode);
return fileNode;
// Do not clean formData temp files to allow for retries.
// Temp files will be deleted later when GC call DiskFileItem#finalize() method or by temp file cleaner.
} catch (AccessDeniedException ade) {
throw new PermissionDeniedException(ade.getMessage());
}
/*
* NOTE: Do not clean formData temp files to allow for retries. It's
* possible for a temp file to remain if max retry attempts are
* made, but this is rare, so leave to usual temp file cleanup.
*/
}
use of org.alfresco.rest.api.model.Node in project alfresco-remote-api by Alfresco.
the class QuickShareLinksImpl method getQuickShareInfo.
private QuickShareLink getQuickShareInfo(NodeRef nodeRef, Map<String, Object> map, boolean noAuth, List<String> includeParam) {
String sharedId = (String) map.get("sharedId");
try {
Map<QName, Serializable> nodeProps = nodeService.getProperties(nodeRef);
ContentData cd = (ContentData) nodeProps.get(ContentModel.PROP_CONTENT);
String mimeType = cd.getMimetype();
String mimeTypeName = mimeTypeService.getDisplaysByMimetype().get(mimeType);
ContentInfo contentInfo = new ContentInfo(mimeType, mimeTypeName, cd.getSize(), cd.getEncoding());
Map<String, UserInfo> mapUserInfo = new HashMap<>(2);
// note: if noAuth mode then don't return userids (to limit disclosure and be consistent with v0 internal)
boolean displayNameOnly = noAuth;
UserInfo modifiedByUser = Node.lookupUserInfo((String) nodeProps.get(ContentModel.PROP_MODIFIER), mapUserInfo, personService, displayNameOnly);
// TODO review - should we return sharedByUser for authenticated users only ?? (not exposed by V0 but needed for "find")
String sharedByUserId = (String) nodeProps.get(QuickShareModel.PROP_QSHARE_SHAREDBY);
UserInfo sharedByUser = Node.lookupUserInfo(sharedByUserId, mapUserInfo, personService, displayNameOnly);
QuickShareLink qs = new QuickShareLink(sharedId, nodeRef.getId());
qs.setName((String) map.get("name"));
qs.setTitle((String) map.get("title"));
qs.setDescription((String) map.get("description"));
qs.setContent(contentInfo);
qs.setModifiedAt((Date) map.get("modified"));
qs.setModifiedByUser(modifiedByUser);
qs.setSharedByUser(sharedByUser);
qs.setExpiresAt((Date) map.get("expiryDate"));
// note: if noAuth mode then do not return allowable operations (eg. but can be optionally returned when finding shared links)
if (!noAuth) {
// Cached document
Node doc = null;
if (includeParam.contains(PARAM_INCLUDE_ALLOWABLEOPERATIONS)) {
if (quickShareService.canDeleteSharedLink(nodeRef, sharedByUserId)) {
// the allowable operations for the shared link
qs.setAllowableOperations(Collections.singletonList(Nodes.OP_DELETE));
}
doc = getNode(nodeRef, includeParam, mapUserInfo);
List<String> allowableOps = doc.getAllowableOperations();
// the allowable operations for the actual file being shared
qs.setAllowableOperationsOnTarget(allowableOps);
}
// in noAuth mode we don't return the path info
if (includeParam.contains(PARAM_INCLUDE_PATH)) {
qs.setPath(nodes.lookupPathInfo(nodeRef, null));
}
if (includeParam.contains(PARAM_INCLUDE_PROPERTIES)) {
if (doc == null) {
doc = getNode(nodeRef, includeParam, mapUserInfo);
}
// Create a map from node properties excluding properties already in this QuickShareLink
Map<String, Object> filteredNodeProperties = filterProps(doc.getProperties(), EXCLUDED_PROPS);
qs.setProperties(filteredNodeProperties);
}
if (includeParam.contains(PARAM_INCLUDE_ISFAVORITE)) {
if (doc == null) {
doc = getNode(nodeRef, includeParam, mapUserInfo);
}
qs.setIsFavorite(doc.getIsFavorite());
}
if (includeParam.contains(PARAM_INCLUDE_ASPECTNAMES)) {
if (doc == null) {
doc = getNode(nodeRef, includeParam, mapUserInfo);
}
qs.setAspectNames(doc.getAspectNames());
}
}
return qs;
} catch (InvalidSharedIdException ex) {
logger.warn("Unable to find: " + sharedId);
throw new EntityNotFoundException(sharedId);
} catch (InvalidNodeRefException inre) {
logger.warn("Unable to find: " + sharedId + " [" + inre.getNodeRef() + "]");
throw new EntityNotFoundException(sharedId);
}
}
Aggregations