From 0211392ff6293233e12cfb7804bbb3bab82e2a8c Mon Sep 17 00:00:00 2001
From: dhrn <14145706+dhrn@users.noreply.github.com>
Date: Fri, 5 Feb 2021 15:25:22 +0530
Subject: [PATCH] Aspect and Type api implementation (#261)
* initial commit
* * added match filters
* api completed
* * removed unwanted changes
* fixed test
* * fix consistant naming of class
* fixed comments
* * fixed comments
* * aspects fixed
* * types added
* * fixed tes and minor improvemment
* * fixed comments
---
.../java/org/alfresco/rest/api/Aspects.java | 37 +++
...Mapper.java => ClassDefinitionMapper.java} | 7 +-
.../java/org/alfresco/rest/api/Types.java | 37 +++
.../api/aspects/AspectEntityResource.java | 66 +++++
.../rest/api/aspects/package-info.java | 30 +++
.../rest/api/impl/AbstractClassImpl.java | 218 ++++++++++++++++
.../alfresco/rest/api/impl/AspectsImpl.java | 171 ++++++++++++
...pl.java => ClassDefinitionMapperImpl.java} | 50 ++--
.../rest/api/impl/CustomModelsImpl.java | 70 ++---
.../org/alfresco/rest/api/impl/NodesImpl.java | 14 +-
.../org/alfresco/rest/api/impl/TypesImpl.java | 171 ++++++++++++
.../rest/api/model/AbstractClass.java | 124 +++++++++
...assModel.java => AbstractCustomClass.java} | 52 ++--
.../org/alfresco/rest/api/model/Aspect.java | 62 +++++
...deDefinition.java => ClassDefinition.java} | 8 +-
...straint.java => ConstraintDefinition.java} | 2 +-
.../alfresco/rest/api/model/CustomAspect.java | 52 ++--
.../alfresco/rest/api/model/CustomType.java | 52 ++--
.../org/alfresco/rest/api/model/Node.java | 6 +-
...nProperty.java => PropertyDefinition.java} | 8 +-
.../org/alfresco/rest/api/model/Type.java | 62 +++++
.../rest/api/types/TypeEntityResource.java | 66 +++++
.../alfresco/rest/api/types/package-info.java | 30 +++
.../alfresco/public-rest-context.xml | 54 +++-
.../api/tests/BaseCustomModelApiTest.java | 10 +-
.../alfresco/rest/api/tests/NodeApiTest.java | 40 +--
.../alfresco/rest/api/tests/TestAspects.java | 244 ++++++++++++++++++
.../alfresco/rest/api/tests/TestTypes.java | 238 +++++++++++++++++
.../api/tests/client/PublicApiClient.java | 49 +++-
.../rest/api/tests/client/data/Aspect.java | 126 +++++++++
.../rest/api/tests/client/data/Node.java | 8 +-
.../rest/api/tests/client/data/Type.java | 126 +++++++++
.../test/resources/models/mycompany-model.xml | 147 +++++++++++
.../src/test/resources/models/test-scan.xml | 84 ++++++
.../test/resources/rest-api-test-context.xml | 2 +
35 files changed, 2325 insertions(+), 198 deletions(-)
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/Aspects.java
rename remote-api/src/main/java/org/alfresco/rest/api/{NodeDefinitionMapper.java => ClassDefinitionMapper.java} (82%)
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/Types.java
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/aspects/AspectEntityResource.java
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/aspects/package-info.java
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/impl/AbstractClassImpl.java
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/impl/AspectsImpl.java
rename remote-api/src/main/java/org/alfresco/rest/api/impl/{NodeDefinitionMapperImpl.java => ClassDefinitionMapperImpl.java} (65%)
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/impl/TypesImpl.java
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/model/AbstractClass.java
rename remote-api/src/main/java/org/alfresco/rest/api/model/{AbstractClassModel.java => AbstractCustomClass.java} (91%)
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/model/Aspect.java
rename remote-api/src/main/java/org/alfresco/rest/api/model/{NodeDefinition.java => ClassDefinition.java} (86%)
rename remote-api/src/main/java/org/alfresco/rest/api/model/{NodeDefinitionConstraint.java => ConstraintDefinition.java} (98%)
rename remote-api/src/main/java/org/alfresco/rest/api/model/{NodeDefinitionProperty.java => PropertyDefinition.java} (93%)
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/model/Type.java
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/types/TypeEntityResource.java
create mode 100644 remote-api/src/main/java/org/alfresco/rest/api/types/package-info.java
create mode 100644 remote-api/src/test/java/org/alfresco/rest/api/tests/TestAspects.java
create mode 100644 remote-api/src/test/java/org/alfresco/rest/api/tests/TestTypes.java
create mode 100644 remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Aspect.java
create mode 100644 remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Type.java
create mode 100644 remote-api/src/test/resources/models/mycompany-model.xml
create mode 100644 remote-api/src/test/resources/models/test-scan.xml
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/Aspects.java b/remote-api/src/main/java/org/alfresco/rest/api/Aspects.java
new file mode 100644
index 0000000000..53da61d772
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/Aspects.java
@@ -0,0 +1,37 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api;
+
+import org.alfresco.rest.api.model.Aspect;
+import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
+import org.alfresco.rest.framework.resource.parameters.Parameters;
+
+public interface Aspects
+{
+ CollectionWithPagingInfo listAspects(Parameters params);
+ Aspect getAspectById(String aspectId);
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/NodeDefinitionMapper.java b/remote-api/src/main/java/org/alfresco/rest/api/ClassDefinitionMapper.java
similarity index 82%
rename from remote-api/src/main/java/org/alfresco/rest/api/NodeDefinitionMapper.java
rename to remote-api/src/main/java/org/alfresco/rest/api/ClassDefinitionMapper.java
index 918be2531d..787f1d6b0f 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/NodeDefinitionMapper.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/ClassDefinitionMapper.java
@@ -25,15 +25,14 @@
*/
package org.alfresco.rest.api;
-import org.alfresco.rest.api.model.NodeDefinition;
-import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.i18n.MessageLookup;
+
/**
* Maps representations from TypeDefinition to NodeDefinition
*
* @author gfertuso
*/
-public interface NodeDefinitionMapper
+public interface ClassDefinitionMapper
{
- NodeDefinition fromTypeDefinition(TypeDefinition typeDefinition, MessageLookup messageLookup);
+ org.alfresco.rest.api.model.ClassDefinition fromDictionaryClassDefinition(org.alfresco.service.cmr.dictionary.ClassDefinition classDefinition, MessageLookup messageLookup);
}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/Types.java b/remote-api/src/main/java/org/alfresco/rest/api/Types.java
new file mode 100644
index 0000000000..4b27ba2233
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/Types.java
@@ -0,0 +1,37 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api;
+
+import org.alfresco.rest.api.model.Type;
+import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
+import org.alfresco.rest.framework.resource.parameters.Parameters;
+
+public interface Types
+{
+ CollectionWithPagingInfo listTypes(Parameters params);
+ Type getType(String aspectId);
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/aspects/AspectEntityResource.java b/remote-api/src/main/java/org/alfresco/rest/api/aspects/AspectEntityResource.java
new file mode 100644
index 0000000000..89a664241c
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/aspects/AspectEntityResource.java
@@ -0,0 +1,66 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api.aspects;
+
+import org.alfresco.rest.api.Aspects;
+import org.alfresco.rest.api.model.Aspect;
+import org.alfresco.rest.framework.resource.EntityResource;
+import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
+import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
+import org.alfresco.rest.framework.resource.parameters.Parameters;
+import org.alfresco.util.ParameterCheck;
+import org.springframework.beans.factory.InitializingBean;
+
+@EntityResource(name = "aspects", title = "Aspects")
+public class AspectEntityResource implements EntityResourceAction.ReadById, EntityResourceAction.Read, InitializingBean
+{
+
+ private Aspects aspects;
+
+ public void setAspects(Aspects aspects)
+ {
+ this.aspects = aspects;
+ }
+
+ @Override
+ public void afterPropertiesSet()
+ {
+ ParameterCheck.mandatory("aspects", this.aspects);
+ }
+
+ @Override
+ public CollectionWithPagingInfo readAll(Parameters params)
+ {
+ return aspects.listAspects(params);
+ }
+
+ @Override
+ public Aspect readById(String id, Parameters parameters)
+ {
+ return aspects.getAspectById(id);
+ }
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/aspects/package-info.java b/remote-api/src/main/java/org/alfresco/rest/api/aspects/package-info.java
new file mode 100644
index 0000000000..0cc3df5afe
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/aspects/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+@WebApi(name="alfresco", scope= Api.SCOPE.PUBLIC, version=1)
+package org.alfresco.rest.api.aspects;
+import org.alfresco.rest.framework.Api;
+import org.alfresco.rest.framework.WebApi;
\ No newline at end of file
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/AbstractClassImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/AbstractClassImpl.java
new file mode 100644
index 0000000000..0868923121
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/AbstractClassImpl.java
@@ -0,0 +1,218 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api.impl;
+
+import org.alfresco.rest.api.model.AbstractClass;
+import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
+import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
+import org.alfresco.rest.framework.resource.parameters.Paging;
+import org.alfresco.rest.framework.resource.parameters.where.Query;
+import org.alfresco.rest.framework.resource.parameters.where.QueryHelper;
+import org.alfresco.rest.workflow.api.impl.MapBasedQueryWalker;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+public class AbstractClassImpl {
+ static String PARAM_MODEL_IDS = "modelIds";
+ static String PARAM_PARENT_IDS = "parentIds";
+ static String PARAM_NAMESPACE_URI = "namespaceUri";
+
+ public CollectionWithPagingInfo createPagedResult(List list, Paging paging)
+ {
+ int skipCount = paging.getSkipCount();
+ int maxItems = paging.getMaxItems();
+ int totalItems = list.size();
+
+ Collections.sort(list);
+
+ if (skipCount >= totalItems)
+ {
+ List empty = Collections.emptyList();
+ return CollectionWithPagingInfo.asPaged(paging, empty, false, totalItems);
+ }
+ else
+ {
+ int end = Math.min(skipCount + maxItems, totalItems);
+ boolean hasMoreItems = totalItems > end;
+ list = list.subList(skipCount, end);
+ return CollectionWithPagingInfo.asPaged(paging, list, hasMoreItems, totalItems);
+ }
+ }
+
+ public boolean filterByNamespace(ModelApiFilter query, QName qName)
+ {
+ //System aspect/type is not allowed
+ if (qName.getNamespaceURI().equals(NamespaceService.SYSTEM_MODEL_1_0_URI))
+ {
+ return false;
+ }
+ if (query != null && query.getMatchedPrefix() != null)
+ {
+ return Pattern.matches(query.getMatchedPrefix(), qName.getNamespaceURI());
+ }
+ if (query != null && query.getNotMatchedPrefix() != null)
+ {
+ return !Pattern.matches(query.getNotMatchedPrefix(), qName.getNamespaceURI());
+ }
+ return true;
+ }
+
+ public ModelApiFilter getQuery(Query queryParameters)
+ {
+ if (queryParameters != null)
+ {
+ ClassQueryWalker propertyWalker = new ClassQueryWalker();
+ QueryHelper.walk(queryParameters, propertyWalker);
+ return new ModelApiFilter(propertyWalker.getModelIds(), propertyWalker.getParentIds(), propertyWalker.getMatchedPrefix(), propertyWalker.getNotMatchedPrefix());
+ }
+ return null;
+ }
+
+ void validateListParam(Set listParam, String paramName)
+ {
+ if (listParam.isEmpty())
+ {
+ throw new IllegalArgumentException(StringUtils.capitalize(paramName) + "s filter list cannot be empty.");
+ }
+
+ listParam.stream()
+ .filter(String::isEmpty)
+ .findAny()
+ .ifPresent(qName -> {
+ throw new IllegalArgumentException(StringUtils.capitalize(paramName) + " cannot be empty (i.e. '')");
+ });
+ }
+
+ public static class ClassQueryWalker extends MapBasedQueryWalker
+ {
+ private Set modelIds = null;
+ private Set parentIds = null;
+ private String notMatchedPrefix = null;
+ private String matchedPrefix = null;
+
+ public ClassQueryWalker()
+ {
+ super(new HashSet<>(Arrays.asList(PARAM_MODEL_IDS, PARAM_PARENT_IDS)), new HashSet<>(Collections.singleton(PARAM_NAMESPACE_URI)));
+ }
+
+ @Override
+ public void in(String propertyName, boolean negated, String... propertyValues)
+ {
+ if (negated)
+ {
+ throw new InvalidArgumentException("Cannot use NOT for " + propertyName);
+ }
+
+ if (propertyName.equalsIgnoreCase(PARAM_MODEL_IDS))
+ {
+ modelIds = new HashSet<>(Arrays.asList(propertyValues));
+ }
+
+ if (propertyName.equalsIgnoreCase(PARAM_PARENT_IDS))
+ {
+ parentIds = new HashSet<>(Arrays.asList(propertyValues));
+ }
+ }
+
+ @Override
+ public void matches(String property, String value, boolean negated)
+ {
+ if (negated && property.equals(PARAM_NAMESPACE_URI))
+ {
+ notMatchedPrefix = value;
+ }
+ else if (property.equals(PARAM_NAMESPACE_URI))
+ {
+ matchedPrefix = value;
+ }
+ }
+
+ public Set getModelIds()
+ {
+ return this.modelIds;
+ }
+
+ public Set getParentIds()
+ {
+ return this.parentIds;
+ }
+
+ public String getNotMatchedPrefix()
+ {
+ return this.notMatchedPrefix;
+ }
+
+ public String getMatchedPrefix()
+ {
+ return this.matchedPrefix;
+ }
+ }
+
+ public static class ModelApiFilter
+ {
+ private Set modelIds;
+ private Set parentIds;
+ private String matchedPrefix;
+ private String notMatchedPrefix;
+
+ public ModelApiFilter(Set modelIds, Set parentIds, String matchedPrefix, String notMatchedPrefix)
+ {
+ this.modelIds = modelIds;
+ this.parentIds = parentIds;
+ this.matchedPrefix = matchedPrefix;
+ this.notMatchedPrefix = notMatchedPrefix;
+ }
+
+ public Set getModelIds()
+ {
+ return modelIds;
+ }
+
+ public String getMatchedPrefix()
+ {
+ return matchedPrefix;
+ }
+
+ public String getNotMatchedPrefix()
+ {
+ return notMatchedPrefix;
+ }
+
+ public Set getParentIds()
+ {
+ return parentIds;
+ }
+ }
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/AspectsImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/AspectsImpl.java
new file mode 100644
index 0000000000..fec0a4057d
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/AspectsImpl.java
@@ -0,0 +1,171 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api.impl;
+
+import org.alfresco.rest.api.Aspects;
+import org.alfresco.rest.api.ClassDefinitionMapper;
+import org.alfresco.rest.api.model.Aspect;
+import org.alfresco.rest.api.model.PropertyDefinition;
+import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
+import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
+import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
+import org.alfresco.rest.framework.resource.parameters.Paging;
+import org.alfresco.rest.framework.resource.parameters.Parameters;
+import org.alfresco.service.cmr.dictionary.AspectDefinition;
+import org.alfresco.service.cmr.dictionary.DictionaryService;
+import org.alfresco.service.cmr.dictionary.ModelDefinition;
+import org.alfresco.service.namespace.NamespaceException;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.PropertyCheck;
+
+import java.util.List;
+import java.util.Collection;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class AspectsImpl extends AbstractClassImpl implements Aspects
+{
+ private DictionaryService dictionaryService;
+ private NamespacePrefixResolver namespaceService;
+ private ClassDefinitionMapper classDefinitionMapper;
+
+ public void setDictionaryService(DictionaryService dictionaryService)
+ {
+ this.dictionaryService = dictionaryService;
+ }
+
+ public void setNamespaceService(NamespacePrefixResolver namespaceService)
+ {
+ this.namespaceService = namespaceService;
+ }
+
+ public void setClassDefinitionMapper(ClassDefinitionMapper classDefinitionMapper)
+ {
+ this.classDefinitionMapper = classDefinitionMapper;
+ }
+
+ public void init()
+ {
+ PropertyCheck.mandatory(this, "dictionaryService", dictionaryService);
+ PropertyCheck.mandatory(this, "namespaceService", namespaceService);
+ PropertyCheck.mandatory(this, "classDefinitionMapper", classDefinitionMapper);
+ }
+
+
+ @Override
+ public CollectionWithPagingInfo listAspects(Parameters params)
+ {
+ Paging paging = params.getPaging();
+ ModelApiFilter query = getQuery(params.getQuery());
+ Stream aspectList = null;
+
+ if (query != null && query.getModelIds() != null)
+ {
+ validateListParam(query.getModelIds(), PARAM_MODEL_IDS);
+ aspectList = query.getModelIds().parallelStream().map(this::getModelAspects).flatMap(Collection::parallelStream);
+ }
+ else if (query != null && query.getParentIds() != null)
+ {
+ validateListParam(query.getParentIds(), PARAM_PARENT_IDS);
+ aspectList = query.getParentIds().parallelStream().map(this::getChildAspects).flatMap(Collection::parallelStream);
+ }
+ else
+ {
+ aspectList = this.dictionaryService.getAllAspects().parallelStream();
+ }
+
+ List allAspects = aspectList.filter((qName) -> filterByNamespace(query, qName))
+ .map((qName) -> this.convertToAspect(dictionaryService.getAspect(qName)))
+ .collect(Collectors.toList());
+ return createPagedResult(allAspects, paging);
+ }
+
+ @Override
+ public Aspect getAspectById(String aspectId)
+ {
+ if (aspectId == null)
+ throw new InvalidArgumentException("Invalid parameter: unknown scheme specified");
+
+ AspectDefinition aspectDefinition = null;
+
+ try
+ {
+ aspectDefinition = dictionaryService.getAspect(QName.createQName(aspectId, this.namespaceService));
+ }
+ catch (NamespaceException exception)
+ {
+ throw new EntityNotFoundException(aspectId);
+ }
+
+ if (aspectDefinition == null)
+ throw new EntityNotFoundException(aspectId);
+
+ return this.convertToAspect(aspectDefinition);
+ }
+
+ public Aspect convertToAspect(AspectDefinition aspectDefinition)
+ {
+ List properties = this.classDefinitionMapper.fromDictionaryClassDefinition(aspectDefinition, dictionaryService).getProperties();
+ return new Aspect(aspectDefinition, dictionaryService, properties);
+ }
+
+ private Collection getModelAspects(String modelId)
+ {
+ ModelDefinition modelDefinition = null;
+
+ if (modelId == null)
+ throw new InvalidArgumentException("modelId is null");
+
+ try
+ {
+ modelDefinition = this.dictionaryService.getModel(QName.createQName(modelId, this.namespaceService));
+ }
+ catch (NamespaceException exception)
+ {
+ throw new InvalidArgumentException(exception.getMessage());
+ }
+
+ return this.dictionaryService.getAspects(modelDefinition.getName());
+ }
+
+ private Collection getChildAspects(String aspectId)
+ {
+ Collection subAspects = null;
+ try
+ {
+ QName parentAspect = QName.createQName(aspectId, this.namespaceService);
+ subAspects = this.dictionaryService.getSubAspects(parentAspect, true);
+ }
+ catch (NamespaceException exception)
+ {
+ throw new InvalidArgumentException(exception.getMessage());
+ }
+
+ return subAspects;
+ }
+}
\ No newline at end of file
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodeDefinitionMapperImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/ClassDefinitionMapperImpl.java
similarity index 65%
rename from remote-api/src/main/java/org/alfresco/rest/api/impl/NodeDefinitionMapperImpl.java
rename to remote-api/src/main/java/org/alfresco/rest/api/impl/ClassDefinitionMapperImpl.java
index edc477e126..b4d44a6394 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodeDefinitionMapperImpl.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/ClassDefinitionMapperImpl.java
@@ -32,13 +32,8 @@ import java.util.Map;
import java.util.stream.Collectors;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
-import org.alfresco.rest.api.NodeDefinitionMapper;
-import org.alfresco.rest.api.model.NodeDefinitionConstraint;
-import org.alfresco.rest.api.model.NodeDefinition;
-import org.alfresco.rest.api.model.NodeDefinitionProperty;
-import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
-import org.alfresco.service.cmr.dictionary.PropertyDefinition;
-import org.alfresco.service.cmr.dictionary.TypeDefinition;
+import org.alfresco.rest.api.ClassDefinitionMapper;
+import org.alfresco.rest.api.model.ClassDefinition;
import org.alfresco.service.cmr.i18n.MessageLookup;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
@@ -47,33 +42,33 @@ import org.alfresco.service.namespace.QName;
*
* @author gfertuso
*/
-public class NodeDefinitionMapperImpl implements NodeDefinitionMapper
+public class ClassDefinitionMapperImpl implements ClassDefinitionMapper
{
private final List EXCLUDED_NS = Arrays.asList(NamespaceService.SYSTEM_MODEL_1_0_URI);
private static final List EXCLUDED_PROPS = Arrays.asList(ContentModel.PROP_CONTENT);
+
@Override
- public NodeDefinition fromTypeDefinition(TypeDefinition typeDefinition,
- MessageLookup messageLookup)
+ public ClassDefinition fromDictionaryClassDefinition(org.alfresco.service.cmr.dictionary.ClassDefinition classDefinition, MessageLookup messageLookup)
{
-
- if (typeDefinition == null)
+ if (classDefinition == null)
{
- throw new AlfrescoRuntimeException("Undefined definition for the node");
+ throw new AlfrescoRuntimeException("Undefined ClassDefinition for the node");
}
- NodeDefinition nodeDefinition = new NodeDefinition();
- nodeDefinition.setProperties(getProperties(typeDefinition.getProperties(), messageLookup));
-
- return nodeDefinition;
+
+ ClassDefinition _classDefinition = new ClassDefinition();
+ _classDefinition.setProperties(getProperties(classDefinition.getProperties(), messageLookup));
+
+ return _classDefinition;
}
- private boolean isPropertyExcluded(QName propertyName)
+ private boolean isPropertyExcluded(QName propertyName)
{
return EXCLUDED_NS.contains(propertyName.getNamespaceURI()) || EXCLUDED_PROPS.contains(propertyName);
}
- private List getProperties(Map propertiesMap, MessageLookup messageLookup)
+ private List getProperties(Map propertiesMap, MessageLookup messageLookup)
{
return propertiesMap.values().stream()
.filter(p -> !isPropertyExcluded(p.getName()))
@@ -81,10 +76,10 @@ public class NodeDefinitionMapperImpl implements NodeDefinitionMapper
.collect(Collectors.toList());
}
- private NodeDefinitionProperty fromPropertyDefinitionToProperty(PropertyDefinition propertyDefinition,
- MessageLookup messageLookup)
+ private org.alfresco.rest.api.model.PropertyDefinition fromPropertyDefinitionToProperty(org.alfresco.service.cmr.dictionary.PropertyDefinition propertyDefinition,
+ MessageLookup messageLookup)
{
- NodeDefinitionProperty property = new NodeDefinitionProperty();
+ org.alfresco.rest.api.model.PropertyDefinition property = new org.alfresco.rest.api.model.PropertyDefinition();
property.setId(propertyDefinition.getName().toPrefixString());
property.setTitle(propertyDefinition.getTitle(messageLookup));
property.setDescription(propertyDefinition.getDescription(messageLookup));
@@ -99,8 +94,8 @@ public class NodeDefinitionMapperImpl implements NodeDefinitionMapper
return property;
}
- private List getConstraints( Collection constraintDefinitions,
- MessageLookup messageLookup)
+ private List getConstraints(Collection constraintDefinitions,
+ MessageLookup messageLookup)
{
return constraintDefinitions.stream()
@@ -109,10 +104,10 @@ public class NodeDefinitionMapperImpl implements NodeDefinitionMapper
.collect(Collectors.toList());
}
- private NodeDefinitionConstraint fromConstraintDefinitionToConstraint(ConstraintDefinition constraintDefinition,
- MessageLookup messageLookup)
+ private org.alfresco.rest.api.model.ConstraintDefinition fromConstraintDefinitionToConstraint(org.alfresco.service.cmr.dictionary.ConstraintDefinition constraintDefinition,
+ MessageLookup messageLookup)
{
- NodeDefinitionConstraint constraint = new NodeDefinitionConstraint();
+ org.alfresco.rest.api.model.ConstraintDefinition constraint = new org.alfresco.rest.api.model.ConstraintDefinition();
constraint.setId(constraintDefinition.getConstraint().getShortName());
constraint.setType(constraintDefinition.getConstraint().getType());
constraint.setTitle(constraintDefinition.getTitle(messageLookup));
@@ -120,5 +115,4 @@ public class NodeDefinitionMapperImpl implements NodeDefinitionMapper
constraint.setParameters(constraintDefinition.getConstraint().getParameters());
return constraint;
}
-
}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/CustomModelsImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/CustomModelsImpl.java
index f1fa39df0d..78f24ace73 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/impl/CustomModelsImpl.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/CustomModelsImpl.java
@@ -1,28 +1,28 @@
-/*
- * #%L
- * Alfresco Remote API
- * %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
- * %%
- * This file is part of the Alfresco software.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * Alfresco is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Alfresco is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Alfresco. If not, see .
- * #L%
- */
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
package org.alfresco.rest.api.impl;
@@ -52,7 +52,7 @@ import org.alfresco.repo.dictionary.M2Type;
import org.alfresco.repo.dictionary.ValueDataTypeValidator;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.rest.api.CustomModels;
-import org.alfresco.rest.api.model.AbstractClassModel;
+import org.alfresco.rest.api.model.AbstractCustomClass;
import org.alfresco.rest.api.model.AbstractCommonDetails;
import org.alfresco.rest.api.model.CustomAspect;
import org.alfresco.rest.api.model.CustomModel;
@@ -331,9 +331,9 @@ public class CustomModelsImpl implements CustomModels
}
}
- private void replacePrefix(List extends AbstractClassModel> existingTypesOrAspects, String modelOldNamespacePrefix, String modelNewNamespacePrefix)
+ private void replacePrefix(List extends AbstractCustomClass> existingTypesOrAspects, String modelOldNamespacePrefix, String modelNewNamespacePrefix)
{
- for(AbstractClassModel classModel : existingTypesOrAspects)
+ for(AbstractCustomClass classModel : existingTypesOrAspects)
{
// Type/Aspect's parent name
String parentName = classModel.getParentName();
@@ -460,7 +460,7 @@ public class CustomModelsImpl implements CustomModels
return updateTypeAspect(modelName, type, parameters);
}
- private T updateTypeAspect(String modelName, T classDef, Parameters parameters)
+ private T updateTypeAspect(String modelName, T classDef, Parameters parameters)
{
// Check the current user is authorised to update the custom model
validateCurrentUser();
@@ -476,7 +476,7 @@ public class CustomModelsImpl implements CustomModels
ModelDetails existingModelDetails = new ModelDetails(getCustomModelImpl(modelName));
- List extends AbstractClassModel> allClassDefs = isAspect ? existingModelDetails.getAspects() : existingModelDetails.getTypes();
+ List extends AbstractCustomClass> allClassDefs = isAspect ? existingModelDetails.getAspects() : existingModelDetails.getTypes();
@SuppressWarnings("unchecked")
T existingClassDef = (T) getObjectByName(allClassDefs, name);
@@ -1186,7 +1186,7 @@ public class CustomModelsImpl implements CustomModels
m2Class.setParentName(parentPrefixedName);
}
- private void validateTypeAspectParent(AbstractClassModel typeAspect, CustomModel existingModel)
+ private void validateTypeAspectParent(AbstractCustomClass typeAspect, CustomModel existingModel)
{
String parentPrefixedName = typeAspect.getParentName();
if (StringUtils.isBlank(parentPrefixedName))
@@ -1305,7 +1305,7 @@ public class CustomModelsImpl implements CustomModels
}
}
- private void mergeProperties(AbstractClassModel existingDetails, AbstractClassModel newDetails, Parameters parameters, boolean isModelActive)
+ private void mergeProperties(AbstractCustomClass existingDetails, AbstractCustomClass newDetails, Parameters parameters, boolean isModelActive)
{
validateList(newDetails.getProperties(), "cmm.rest_api.properties_empty_null");
@@ -1386,7 +1386,7 @@ public class CustomModelsImpl implements CustomModels
}
}
- private void deleteProperty(AbstractClassModel existingClassModel, String propertyName)
+ private void deleteProperty(AbstractCustomClass existingClassModel, String propertyName)
{
// Transform existing properties into a map
Map existingProperties = transformToMap(existingClassModel.getProperties(), toNameFunction());
@@ -1427,9 +1427,9 @@ public class CustomModelsImpl implements CustomModels
return result;
}
- private void validateTypeAspectDelete(Collection extends AbstractClassModel> list, String classPrefixedName)
+ private void validateTypeAspectDelete(Collection extends AbstractCustomClass> list, String classPrefixedName)
{
- for(AbstractClassModel acm : list)
+ for(AbstractCustomClass acm : list)
{
if(classPrefixedName.equals(acm.getParentName()))
{
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java
index 29b7280f50..ed8bb25a44 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/NodesImpl.java
@@ -79,12 +79,12 @@ import org.alfresco.repo.version.VersionModel;
import org.alfresco.repo.virtual.store.VirtualStore;
import org.alfresco.rest.antlr.WhereClauseParser;
import org.alfresco.rest.api.Activities;
-import org.alfresco.rest.api.NodeDefinitionMapper;
+import org.alfresco.rest.api.ClassDefinitionMapper;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.QuickShareLinks;
import org.alfresco.rest.api.model.AssocChild;
import org.alfresco.rest.api.model.AssocTarget;
-import org.alfresco.rest.api.model.NodeDefinition;
+import org.alfresco.rest.api.model.ClassDefinition;
import org.alfresco.rest.api.model.Document;
import org.alfresco.rest.api.model.Folder;
import org.alfresco.rest.api.model.LockInfo;
@@ -214,7 +214,7 @@ public class NodesImpl implements Nodes
private RetryingTransactionHelper retryingTransactionHelper;
private LockService lockService;
private VirtualStore smartStore; // note: remove as part of REPO-1173
- private NodeDefinitionMapper nodeDefinitionMapper;
+ private ClassDefinitionMapper classDefinitionMapper;
private enum Activity_Type
{
@@ -328,9 +328,9 @@ public class NodesImpl implements Nodes
this.smartStore = smartStore;
}
- public void setNodeDefinitionMapper(NodeDefinitionMapper nodeDefinitionMapper)
+ public void setClassDefinitionMapper(ClassDefinitionMapper classDefinitionMapper)
{
- this.nodeDefinitionMapper = nodeDefinitionMapper;
+ this.classDefinitionMapper = classDefinitionMapper;
}
// excluded namespaces (aspects, properties, assoc types)
@@ -1041,8 +1041,8 @@ public class NodesImpl implements Nodes
if (includeParam.contains(PARAM_INCLUDE_DEFINITION))
{
- NodeDefinition nodeDefinition = nodeDefinitionMapper.fromTypeDefinition(getTypeDefinition(nodeRef), dictionaryService);
- node.setDefinition(nodeDefinition);
+ ClassDefinition classDefinition = classDefinitionMapper.fromDictionaryClassDefinition(getTypeDefinition(nodeRef), dictionaryService);
+ node.setDefinition(classDefinition);
}
node.setNodeType(nodeTypeQName.toPrefixString(namespaceService));
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/impl/TypesImpl.java b/remote-api/src/main/java/org/alfresco/rest/api/impl/TypesImpl.java
new file mode 100644
index 0000000000..03473dadc6
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/impl/TypesImpl.java
@@ -0,0 +1,171 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api.impl;
+
+import org.alfresco.rest.api.Types;
+import org.alfresco.rest.api.ClassDefinitionMapper;
+import org.alfresco.rest.api.model.Type;
+import org.alfresco.rest.api.model.PropertyDefinition;
+import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
+import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
+import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
+import org.alfresco.rest.framework.resource.parameters.Paging;
+import org.alfresco.rest.framework.resource.parameters.Parameters;
+import org.alfresco.service.cmr.dictionary.DictionaryService;
+import org.alfresco.service.cmr.dictionary.ModelDefinition;
+import org.alfresco.service.cmr.dictionary.TypeDefinition;
+import org.alfresco.service.namespace.NamespaceException;
+import org.alfresco.service.namespace.NamespacePrefixResolver;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.PropertyCheck;
+
+import java.util.List;
+import java.util.Collection;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class TypesImpl extends AbstractClassImpl implements Types
+{
+ private DictionaryService dictionaryService;
+ private NamespacePrefixResolver namespaceService;
+ private ClassDefinitionMapper classDefinitionMapper;
+
+ public void setDictionaryService(DictionaryService dictionaryService)
+ {
+ this.dictionaryService = dictionaryService;
+ }
+
+ public void setNamespaceService(NamespacePrefixResolver namespaceService)
+ {
+ this.namespaceService = namespaceService;
+ }
+
+ public void setClassDefinitionMapper(ClassDefinitionMapper classDefinitionMapper)
+ {
+ this.classDefinitionMapper = classDefinitionMapper;
+ }
+
+ public void init()
+ {
+ PropertyCheck.mandatory(this, "dictionaryService", dictionaryService);
+ PropertyCheck.mandatory(this, "namespaceService", namespaceService);
+ PropertyCheck.mandatory(this, "classDefinitionMapper", classDefinitionMapper);
+ }
+
+
+ @Override
+ public CollectionWithPagingInfo listTypes(Parameters params)
+ {
+ Paging paging = params.getPaging();
+ ModelApiFilter query = getQuery(params.getQuery());
+ Stream typeList = null;
+
+ if (query != null && query.getModelIds() != null)
+ {
+ validateListParam(query.getModelIds(), PARAM_MODEL_IDS);
+ typeList = query.getModelIds().parallelStream().map(this::getModelTypes).flatMap(Collection::parallelStream);
+ }
+ else if (query != null && query.getParentIds() != null)
+ {
+ validateListParam(query.getParentIds(), PARAM_PARENT_IDS);
+ typeList = query.getParentIds().parallelStream().map(this::getChildTypes).flatMap(Collection::parallelStream);
+ }
+ else
+ {
+ typeList = this.dictionaryService.getAllTypes().parallelStream();
+ }
+
+ List allTypes = typeList.filter((qName) -> filterByNamespace(query, qName))
+ .map((qName) -> this.convertToType(dictionaryService.getType(qName)))
+ .collect(Collectors.toList());
+ return createPagedResult(allTypes, paging);
+ }
+
+ @Override
+ public Type getType(String typeId)
+ {
+ if (typeId == null)
+ throw new InvalidArgumentException("Invalid parameter: unknown scheme specified");
+
+ TypeDefinition typeDefinition = null;
+
+ try
+ {
+ typeDefinition = dictionaryService.getType(QName.createQName(typeId, this.namespaceService));
+ }
+ catch (NamespaceException exception)
+ {
+ throw new EntityNotFoundException(typeId);
+ }
+
+ if (typeDefinition == null)
+ throw new EntityNotFoundException(typeId);
+
+ return this.convertToType(typeDefinition);
+ }
+
+ public Type convertToType(TypeDefinition typeDefinition)
+ {
+ List properties = this.classDefinitionMapper.fromDictionaryClassDefinition(typeDefinition, dictionaryService).getProperties();
+ return new Type(typeDefinition, dictionaryService, properties);
+ }
+
+ private Collection getModelTypes(String modelId)
+ {
+ ModelDefinition modelDefinition = null;
+
+ if (modelId == null)
+ throw new InvalidArgumentException("modelId is null");
+
+ try
+ {
+ modelDefinition = this.dictionaryService.getModel(QName.createQName(modelId, this.namespaceService));
+ }
+ catch (NamespaceException exception)
+ {
+ throw new InvalidArgumentException(exception.getMessage());
+ }
+
+ return this.dictionaryService.getTypes(modelDefinition.getName());
+ }
+
+ private Collection getChildTypes(String typeId)
+ {
+ Collection subTypes = null;
+ try
+ {
+ QName parentType = QName.createQName(typeId, this.namespaceService);
+ subTypes = this.dictionaryService.getSubTypes(parentType, true);
+ }
+ catch (NamespaceException exception)
+ {
+ throw new InvalidArgumentException(exception.getMessage());
+ }
+
+ return subTypes;
+ }
+}
\ No newline at end of file
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/AbstractClass.java b/remote-api/src/main/java/org/alfresco/rest/api/model/AbstractClass.java
new file mode 100644
index 0000000000..cac150a299
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/AbstractClass.java
@@ -0,0 +1,124 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api.model;
+
+import org.alfresco.service.namespace.QName;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public abstract class AbstractClass extends ClassDefinition implements Comparable
+{
+ String id;
+ String title;
+ String description;
+ String parentId;
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public void setId(String id)
+ {
+ this.id = id;
+ }
+
+ public String getTitle()
+ {
+ return this.title;
+ }
+
+ public void setTitle(String title)
+ {
+ this.title = title;
+ }
+
+ public String getDescription()
+ {
+ return this.description;
+ }
+
+ public void setDescription(String description)
+ {
+ this.description = description;
+ }
+
+ public String getParentId()
+ {
+ return parentId;
+ }
+
+ public void setParentId(String parentId)
+ {
+ this.parentId = parentId;
+ }
+
+ List setList(List sourceList)
+ {
+ if (sourceList == null)
+ {
+ return Collections. emptyList();
+ }
+ return new ArrayList<>(sourceList);
+ }
+
+ String getParentNameAsString(QName parentQName)
+ {
+ if (parentQName != null)
+ {
+ return parentQName.toPrefixString();
+ }
+ return null;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ return super.equals(obj);
+ }
+
+ @Override
+ public int compareTo(AbstractClass other)
+ {
+ return this.id.compareTo(other.getId());
+ }
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/AbstractClassModel.java b/remote-api/src/main/java/org/alfresco/rest/api/model/AbstractCustomClass.java
similarity index 91%
rename from remote-api/src/main/java/org/alfresco/rest/api/model/AbstractClassModel.java
rename to remote-api/src/main/java/org/alfresco/rest/api/model/AbstractCustomClass.java
index 9146ef9c30..28fc114375 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/model/AbstractClassModel.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/AbstractCustomClass.java
@@ -1,28 +1,28 @@
-/*
- * #%L
- * Alfresco Remote API
- * %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
- * %%
- * This file is part of the Alfresco software.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * Alfresco is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Alfresco is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Alfresco. If not, see .
- * #L%
- */
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
package org.alfresco.rest.api.model;
@@ -35,7 +35,7 @@ import org.alfresco.service.namespace.QName;
/**
* @author Jamal Kaabi-Mofrad
*/
-public abstract class AbstractClassModel extends AbstractCommonDetails
+public abstract class AbstractCustomClass extends AbstractCommonDetails
{
/* package */String parentName;
/* package */List properties = Collections.emptyList();
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/Aspect.java b/remote-api/src/main/java/org/alfresco/rest/api/model/Aspect.java
new file mode 100644
index 0000000000..6bf9cf3494
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/Aspect.java
@@ -0,0 +1,62 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api.model;
+
+import org.alfresco.service.cmr.dictionary.AspectDefinition;
+import org.alfresco.service.cmr.i18n.MessageLookup;
+
+import java.util.List;
+
+public class Aspect extends AbstractClass
+{
+ public Aspect()
+ {
+ }
+
+ public Aspect(AspectDefinition aspectDefinition, MessageLookup messageLookup, List properties)
+ {
+ this.id = aspectDefinition.getName().toPrefixString();
+ this.title = aspectDefinition.getTitle(messageLookup);
+ this.description = aspectDefinition.getDescription(messageLookup);
+ this.parentId = getParentNameAsString(aspectDefinition.getParentName());
+ this.properties = setList(properties);
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder(512);
+ builder.append("Aspect [id=").append(this.id)
+ .append(", title=").append(this.title)
+ .append(", description=").append(this.description)
+ .append(", parentId=").append(parentId)
+ .append(", properties=").append(properties)
+ .append(']');
+ return builder.toString();
+ }
+}
+
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/NodeDefinition.java b/remote-api/src/main/java/org/alfresco/rest/api/model/ClassDefinition.java
similarity index 86%
rename from remote-api/src/main/java/org/alfresco/rest/api/model/NodeDefinition.java
rename to remote-api/src/main/java/org/alfresco/rest/api/model/ClassDefinition.java
index 227a150623..1fe5b80b08 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/model/NodeDefinition.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/ClassDefinition.java
@@ -31,17 +31,17 @@ import java.util.List;
*
* @author gfertuso
*/
-public class NodeDefinition
+public class ClassDefinition
{
- List properties;
+ List properties;
- public List getProperties()
+ public List getProperties()
{
return properties;
}
- public void setProperties(List properties)
+ public void setProperties(List properties)
{
this.properties = properties;
}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/NodeDefinitionConstraint.java b/remote-api/src/main/java/org/alfresco/rest/api/model/ConstraintDefinition.java
similarity index 98%
rename from remote-api/src/main/java/org/alfresco/rest/api/model/NodeDefinitionConstraint.java
rename to remote-api/src/main/java/org/alfresco/rest/api/model/ConstraintDefinition.java
index 8a7cbcb6fc..632605e871 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/model/NodeDefinitionConstraint.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/ConstraintDefinition.java
@@ -31,7 +31,7 @@ import java.util.Map;
*
* @author gfertuso
*/
-public class NodeDefinitionConstraint
+public class ConstraintDefinition
{
private String id;
private String type;
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/CustomAspect.java b/remote-api/src/main/java/org/alfresco/rest/api/model/CustomAspect.java
index 6715f109d1..1e971495f9 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/model/CustomAspect.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/CustomAspect.java
@@ -1,28 +1,28 @@
-/*
- * #%L
- * Alfresco Remote API
- * %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
- * %%
- * This file is part of the Alfresco software.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * Alfresco is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Alfresco is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Alfresco. If not, see .
- * #L%
- */
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
package org.alfresco.rest.api.model;
@@ -34,7 +34,7 @@ import org.alfresco.service.cmr.i18n.MessageLookup;
/**
* @author Jamal Kaabi-Mofrad
*/
-public class CustomAspect extends AbstractClassModel
+public class CustomAspect extends AbstractCustomClass
{
public CustomAspect()
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/CustomType.java b/remote-api/src/main/java/org/alfresco/rest/api/model/CustomType.java
index bfaf5dc585..1865c12d3d 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/model/CustomType.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/CustomType.java
@@ -1,28 +1,28 @@
-/*
- * #%L
- * Alfresco Remote API
- * %%
- * Copyright (C) 2005 - 2016 Alfresco Software Limited
- * %%
- * This file is part of the Alfresco software.
- * If the software was purchased under a paid Alfresco license, the terms of
- * the paid license agreement will prevail. Otherwise, the software is
- * provided under the following open source license terms:
- *
- * Alfresco is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Alfresco is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Alfresco. If not, see .
- * #L%
- */
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
package org.alfresco.rest.api.model;
@@ -34,7 +34,7 @@ import org.alfresco.service.cmr.i18n.MessageLookup;
/**
* @author Jamal Kaabi-Mofrad
*/
-public class CustomType extends AbstractClassModel
+public class CustomType extends AbstractCustomClass
{
public CustomType()
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/Node.java b/remote-api/src/main/java/org/alfresco/rest/api/model/Node.java
index 9f3827d8f4..9c98efee6f 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/model/Node.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/Node.java
@@ -95,7 +95,7 @@ public class Node implements Comparable
protected List allowableOperations;
protected NodePermissions nodePermissions;
- protected NodeDefinition definition;
+ protected ClassDefinition definition;
//optional SearchEntry (only ever returned from a search)
protected SearchEntry search = null;
@@ -470,12 +470,12 @@ public class Node implements Comparable
this.secondaryChildren = secondaryChildren;
}
- public NodeDefinition getDefinition()
+ public ClassDefinition getDefinition()
{
return definition;
}
- public void setDefinition(NodeDefinition definition)
+ public void setDefinition(ClassDefinition definition)
{
this.definition = definition;
}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/NodeDefinitionProperty.java b/remote-api/src/main/java/org/alfresco/rest/api/model/PropertyDefinition.java
similarity index 93%
rename from remote-api/src/main/java/org/alfresco/rest/api/model/NodeDefinitionProperty.java
rename to remote-api/src/main/java/org/alfresco/rest/api/model/PropertyDefinition.java
index c07d02c066..10717e7778 100644
--- a/remote-api/src/main/java/org/alfresco/rest/api/model/NodeDefinitionProperty.java
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/PropertyDefinition.java
@@ -31,7 +31,7 @@ import java.util.List;
*
* @author gfertuso
*/
-public class NodeDefinitionProperty
+public class PropertyDefinition
{
private String id;
private String title;
@@ -42,7 +42,7 @@ public class NodeDefinitionProperty
private Boolean isMandatory;
private Boolean isMandatoryEnforced;
private Boolean isProtected;
- private List constraints;
+ private List constraints;
public String getId()
{
@@ -104,12 +104,12 @@ public class NodeDefinitionProperty
this.isProtected = isProtected;
}
- public List getConstraints()
+ public List getConstraints()
{
return constraints;
}
- public void setConstraints(List constraints)
+ public void setConstraints(List constraints)
{
this.constraints = constraints;
}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/model/Type.java b/remote-api/src/main/java/org/alfresco/rest/api/model/Type.java
new file mode 100644
index 0000000000..3eb8fdded6
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/model/Type.java
@@ -0,0 +1,62 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api.model;
+
+import org.alfresco.service.cmr.dictionary.TypeDefinition;
+import org.alfresco.service.cmr.i18n.MessageLookup;
+
+import java.util.List;
+
+public class Type extends AbstractClass
+{
+ public Type()
+ {
+ }
+
+ public Type(TypeDefinition typeDefinition, MessageLookup messageLookup, List properties)
+ {
+ this.id = typeDefinition.getName().toPrefixString();
+ this.title = typeDefinition.getTitle(messageLookup);
+ this.description = typeDefinition.getDescription(messageLookup);
+ this.parentId = getParentNameAsString(typeDefinition.getParentName());
+ this.properties = setList(properties);
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder(512);
+ builder.append("Type [id=").append(this.id)
+ .append(", title=").append(this.title)
+ .append(", description=").append(this.description)
+ .append(", parentId=").append(parentId)
+ .append(", properties=").append(properties)
+ .append(']');
+ return builder.toString();
+ }
+}
+
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/types/TypeEntityResource.java b/remote-api/src/main/java/org/alfresco/rest/api/types/TypeEntityResource.java
new file mode 100644
index 0000000000..1f8087cd44
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/types/TypeEntityResource.java
@@ -0,0 +1,66 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api.types;
+
+import org.alfresco.rest.api.Types;
+import org.alfresco.rest.api.model.Type;
+import org.alfresco.rest.framework.resource.EntityResource;
+import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
+import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
+import org.alfresco.rest.framework.resource.parameters.Parameters;
+import org.alfresco.util.ParameterCheck;
+import org.springframework.beans.factory.InitializingBean;
+
+@EntityResource(name = "types", title = "types")
+public class TypeEntityResource implements EntityResourceAction.ReadById, EntityResourceAction.Read, InitializingBean
+{
+
+ private Types types;
+
+ public void setTypes(Types types)
+ {
+ this.types = types;
+ }
+
+ @Override
+ public void afterPropertiesSet()
+ {
+ ParameterCheck.mandatory("types", this.types);
+ }
+
+ @Override
+ public CollectionWithPagingInfo readAll(Parameters params)
+ {
+ return types.listTypes(params);
+ }
+
+ @Override
+ public Type readById(String id, Parameters parameters)
+ {
+ return types.getType(id);
+ }
+}
diff --git a/remote-api/src/main/java/org/alfresco/rest/api/types/package-info.java b/remote-api/src/main/java/org/alfresco/rest/api/types/package-info.java
new file mode 100644
index 0000000000..274cd64aa4
--- /dev/null
+++ b/remote-api/src/main/java/org/alfresco/rest/api/types/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+@WebApi(name="alfresco", scope= Api.SCOPE.PUBLIC, version=1)
+package org.alfresco.rest.api.types;
+import org.alfresco.rest.framework.Api;
+import org.alfresco.rest.framework.WebApi;
\ No newline at end of file
diff --git a/remote-api/src/main/resources/alfresco/public-rest-context.xml b/remote-api/src/main/resources/alfresco/public-rest-context.xml
index 4fc9af0e64..2d9a20b0f4 100644
--- a/remote-api/src/main/resources/alfresco/public-rest-context.xml
+++ b/remote-api/src/main/resources/alfresco/public-rest-context.xml
@@ -530,7 +530,7 @@
-
+
@@ -542,7 +542,7 @@
-
+
@@ -781,7 +781,7 @@
-
+
org.alfresco.rest.api.Sites
@@ -1491,4 +1491,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.Aspects
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.Types
+
+
+
+
+
+
+
+
+
+
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/tests/BaseCustomModelApiTest.java b/remote-api/src/test/java/org/alfresco/rest/api/tests/BaseCustomModelApiTest.java
index 18ad636b48..26a92db764 100644
--- a/remote-api/src/test/java/org/alfresco/rest/api/tests/BaseCustomModelApiTest.java
+++ b/remote-api/src/test/java/org/alfresco/rest/api/tests/BaseCustomModelApiTest.java
@@ -33,7 +33,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
-import org.alfresco.rest.api.model.AbstractClassModel;
+import org.alfresco.rest.api.model.AbstractCustomClass;
import org.alfresco.rest.api.model.CustomAspect;
import org.alfresco.rest.api.model.CustomModel;
import org.alfresco.rest.api.model.CustomModel.ModelStatus;
@@ -158,10 +158,10 @@ public class BaseCustomModelApiTest extends AbstractBaseApiTest
return customModel;
}
- protected T createTypeAspect(Class glazz, String modelName, String typeAspectName, String title, String desc,
- String parent) throws Exception
+ protected T createTypeAspect(Class glazz, String modelName, String typeAspectName, String title, String desc,
+ String parent) throws Exception
{
- AbstractClassModel classModel = null;
+ AbstractCustomClass classModel = null;
String uri = "cmm/" + modelName;
if (glazz.equals(CustomType.class))
{
@@ -194,7 +194,7 @@ public class BaseCustomModelApiTest extends AbstractBaseApiTest
assertTrue("Two models are not equal. Expected:<" + expectedModel.toString() + "> but was:<" + actualModel.toString() + ">", result);
}
- protected void compareCustomTypesAspects(AbstractClassModel expectedDetails, AbstractClassModel actualDetails, String... excludeFields)
+ protected void compareCustomTypesAspects(AbstractCustomClass expectedDetails, AbstractCustomClass actualDetails, String... excludeFields)
{
List expectedProps = expectedDetails.getProperties();
List actualProps = actualDetails.getProperties();
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java b/remote-api/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java
index dde673be98..247a60df9b 100644
--- a/remote-api/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java
+++ b/remote-api/src/test/java/org/alfresco/rest/api/tests/NodeApiTest.java
@@ -62,11 +62,11 @@ import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.rest.AbstractSingleNetworkSiteTest;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.LockInfo;
-import org.alfresco.rest.api.model.NodeDefinition;
-import org.alfresco.rest.api.model.NodeDefinitionConstraint;
+import org.alfresco.rest.api.model.ClassDefinition;
+import org.alfresco.rest.api.model.ConstraintDefinition;
import org.alfresco.rest.api.model.NodePermissions;
import org.alfresco.rest.api.model.NodeTarget;
-import org.alfresco.rest.api.model.NodeDefinitionProperty;
+import org.alfresco.rest.api.model.PropertyDefinition;
import org.alfresco.rest.api.model.Site;
import org.alfresco.rest.api.nodes.NodesEntityResource;
import org.alfresco.rest.api.tests.client.HttpResponse;
@@ -6173,19 +6173,19 @@ public class NodeApiTest extends AbstractSingleNetworkSiteTest
params.put("include", "definition");
response = getSingle(NodesEntityResource.class, nodeId, params, 200);
nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
- NodeDefinition nodeDefinition = nodeResp.getDefinition();
- assertNotNull(nodeDefinition);
- checkDefinitionProperties(nodeDefinition.getProperties());
+ ClassDefinition classDefinition = nodeResp.getDefinition();
+ assertNotNull(classDefinition);
+ checkDefinitionProperties(classDefinition.getProperties());
}
- private void checkDefinitionProperties(List properties)
+ private void checkDefinitionProperties(List properties)
{
assertNotNull(properties);
shouldNotContainSystemProperties(properties);
shouldContainParentProperties(properties);
shouldContainAspectProperties(properties);
- NodeDefinitionProperty testProperty = properties.stream().
+ PropertyDefinition testProperty = properties.stream().
filter(property ->
property.getId().equals("cm:name"))
.findFirst()
@@ -6202,7 +6202,7 @@ public class NodeApiTest extends AbstractSingleNetworkSiteTest
}
- private void shouldNotContainSystemProperties(List properties)
+ private void shouldNotContainSystemProperties(List properties)
{
assertTrue(properties.stream()
.noneMatch(property ->
@@ -6210,41 +6210,41 @@ public class NodeApiTest extends AbstractSingleNetworkSiteTest
property.getId().equals(ContentModel.PROP_CONTENT.toPrefixString(namespaceService))));
}
- private void shouldContainParentProperties(List properties)
+ private void shouldContainParentProperties(List properties)
{
assertTrue(properties.stream()
.anyMatch(property ->
property.getId().equals("cm:name")));
}
- private void shouldContainAspectProperties(List properties)
+ private void shouldContainAspectProperties(List properties)
{
- NodeDefinitionProperty mandatoryAspectProperty = properties.stream()
+ PropertyDefinition mandatoryAspectProperty = properties.stream()
.filter(property -> property.getId().equals("cm:created"))
.findFirst()
.get();
assertNotNull(mandatoryAspectProperty);
- NodeDefinitionProperty nodeAspectProperty = properties.stream()
+ PropertyDefinition nodeAspectProperty = properties.stream()
.filter(property -> property.getId().equals("cm:title"))
.findFirst()
.get();
assertNotNull(nodeAspectProperty);
}
- private void checkPropertyConstraints(List constraints)
+ private void checkPropertyConstraints(List constraints)
{
assertNotNull(constraints);
- NodeDefinitionConstraint nodeDefinitionConstraint = constraints.stream()
+ ConstraintDefinition constraintDefinition = constraints.stream()
.filter(constraint -> constraint.getId().equals("cm:filename"))
.findFirst()
.get();
- assertNotNull(nodeDefinitionConstraint);
- assertEquals("REGEX", nodeDefinitionConstraint.getType());
- Map constraintParameters = nodeDefinitionConstraint.getParameters();
+ assertNotNull(constraintDefinition);
+ assertEquals("REGEX", constraintDefinition.getType());
+ Map constraintParameters = constraintDefinition.getParameters();
assertNotNull(constraintParameters);
- assertNull(nodeDefinitionConstraint.getDescription());
- assertNull(nodeDefinitionConstraint.getTitle());
+ assertNull(constraintDefinition.getDescription());
+ assertNull(constraintDefinition.getTitle());
assertEquals(2, constraintParameters.size());
assertEquals("(.*[\\\"\\*\\\\\\>\\<\\?\\/\\:\\|]+.*)|(.*[\\.]?.*[\\.]+$)|(.*[ ]+$)", constraintParameters.get("expression"));
assertFalse((Boolean) constraintParameters.get("requiresMatch"));
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/tests/TestAspects.java b/remote-api/src/test/java/org/alfresco/rest/api/tests/TestAspects.java
new file mode 100644
index 0000000000..ab6ec1a841
--- /dev/null
+++ b/remote-api/src/test/java/org/alfresco/rest/api/tests/TestAspects.java
@@ -0,0 +1,244 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api.tests;
+
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.rest.api.tests.client.PublicApiClient;
+import org.alfresco.rest.api.tests.client.PublicApiException;
+import org.alfresco.rest.api.tests.client.RequestContext;
+import org.apache.commons.httpclient.HttpStatus;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+public class TestAspects extends AbstractBaseApiTest
+{
+
+ private PublicApiClient.Paging paging = getPaging(0, 10);
+ PublicApiClient.ListResponse aspects = null;
+ org.alfresco.rest.api.tests.client.data.Aspect aspect, childAspect = null, smartFilter = null, rescanAspect = null;
+ Map otherParams = new HashMap<>();
+
+ @Before
+ public void setup() throws Exception
+ {
+ super.setup();
+
+ childAspect = new org.alfresco.rest.api.tests.client.data.Aspect();
+ childAspect.setId("mycompany:childAspect");
+ childAspect.setTitle("Child Aspect");
+ childAspect.setDescription("Child Aspect Description");
+ childAspect.setParentId("smf:smartFolder");
+
+ rescanAspect = new org.alfresco.rest.api.tests.client.data.Aspect();
+ rescanAspect.setId("test:rescan");
+ rescanAspect.setTitle("rescan");
+ rescanAspect.setDescription("Doc that required to scan ");
+
+ smartFilter = new org.alfresco.rest.api.tests.client.data.Aspect();
+ smartFilter.setId("test:smartFilter");
+ smartFilter.setTitle("Smart filter");
+ smartFilter.setDescription("Smart Filter");
+ smartFilter.setParentId("cm:auditable");
+ }
+
+ @Test
+ public void testAllAspects() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ assertTrue(aspects.getPaging().getTotalItems() > 135);
+ assertTrue(aspects.getPaging().getHasMoreItems());
+
+ paging.setSkipCount(130);
+ paging.setMaxItems(50);
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ assertFalse(aspects.getPaging().getHasMoreItems());
+ }
+
+ @Test
+ public void filterAspectsByNamespace() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ otherParams.put("where", "(namespaceUri matches('http://www.mycompany.com/model.*'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ assertEquals(aspects.getPaging().getTotalItems(), Integer.valueOf(4));
+ assertFalse(aspects.getPaging().getHasMoreItems());
+
+ otherParams.put("where", "(not namespaceUri matches('http://www.mycompany.com/model.*'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ assertTrue(aspects.getPaging().getTotalItems() > 130);
+ assertTrue(aspects.getPaging().getHasMoreItems());
+ }
+
+ @Test
+ public void filterAspectsByParentId() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ otherParams.put("where", "(parentIds in ('smf:smartFolder','cm:auditable'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ aspects.getList().get(1).expected(childAspect);
+ assertEquals(aspects.getPaging().getTotalItems(), Integer.valueOf(4));
+ assertFalse(aspects.getPaging().getHasMoreItems());
+
+ otherParams.put("where", "(parentIds in ('smf:smartFolder','cm:auditable') AND namespaceUri matches('http://www.test.*'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ aspects.getList().get(0).expected(smartFilter);
+ assertEquals(aspects.getPaging().getTotalItems(), Integer.valueOf(1));
+
+ otherParams.put("where", "(parentIds in ('smf:smartFolder','cm:auditable') AND not namespaceUri matches('http://www.test.*'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ aspects.getList().get(1).expected(childAspect);
+ assertEquals(aspects.getPaging().getTotalItems(), Integer.valueOf(3));
+
+ // match everything
+ otherParams.put("where", "(parentIds in ('smf:smartFolder','cm:auditable') AND namespaceUri matches('.*'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ assertEquals(aspects.getPaging().getTotalItems(), Integer.valueOf(4));
+
+ // match nothing
+ otherParams.put("where", "(parentIds in ('smf:smartFolder,cm:auditable') AND not namespaceUri matches('.*'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ assertEquals(aspects.getPaging().getTotalItems(), Integer.valueOf(0));
+ }
+
+ @Test
+ public void filterAspectsByModelId() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ otherParams.put("where", "(modelIds in ('mycompany:model','test:scan'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ assertEquals(aspects.getPaging().getTotalItems(), Integer.valueOf(6));
+ assertFalse(aspects.getPaging().getHasMoreItems());
+
+
+ otherParams.put("where", "(modelIds in ('mycompany:model','test:scan') AND namespaceUri matches('http://www.test.*'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ aspects.getList().get(0).expected(rescanAspect);
+ aspects.getList().get(1).expected(smartFilter);
+ assertEquals(aspects.getPaging().getTotalItems(), Integer.valueOf(2));
+
+ otherParams.put("where", "(modelIds in ('mycompany:model','test:scan') AND not namespaceUri matches('http://www.test.*'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ assertEquals(aspects.getPaging().getTotalItems(), Integer.valueOf(4));
+
+ otherParams.put("where", "(modelIds in ('mycompany:model','test:scan') AND namespaceUri matches('.*'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ assertEquals(aspects.getPaging().getTotalItems(), Integer.valueOf(6));
+
+ otherParams.put("where", "(modelIds in ('mycompany:model','test:scan') AND not namespaceUri matches('.*'))");
+ aspects = publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ assertEquals(aspects.getPaging().getTotalItems(), Integer.valueOf(0));
+ }
+
+ @Test
+ public void testAspectsById() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ aspect = publicApiClient.aspects().getAspect("mycompany:childAspect");
+ aspect.expected(childAspect);
+ }
+
+ @Test
+ public void testListAspectByInvalidValue() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ testListAspectException("(modelIds in ('mycompany:model','unknown:model','known:model'))");
+ testListAspectException("(modelIds in ('unknown:model','mycompany:model'))");
+ testListAspectException("(modelIds in (' ',' ',' ')");
+ testListAspectException("(parentIds in ('smf:smartFolder','unknown:aspect'))");
+ testListAspectException("(parentIds in ('unknown:aspect','smf:smartFolder'))");
+ testListAspectException("(parentIds in (' ',' ',' ')");
+ testListAspectException("(namespaceUri matches('*'))"); // wrong pattern
+ }
+
+ @Test
+ public void testGetAspectByInvalidValue() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ testGetAspectExceptions("unknown:childAspect");
+ testGetAspectExceptions("aspect:");
+ testGetAspectExceptions("aspect");
+ }
+
+
+ private void testGetAspectExceptions(String aspectId)
+ {
+ try
+ {
+ publicApiClient.aspects().getAspect(aspectId);
+ fail("Aspect not found expected");
+ }
+ catch (PublicApiException e)
+ {
+ assertEquals(HttpStatus.SC_NOT_FOUND, e.getHttpResponse().getStatusCode());
+ }
+ }
+
+ private void testListAspectException(String query)
+ {
+ try
+ {
+ otherParams.put("where", query);
+ publicApiClient.aspects().getAspects(createParams(paging, otherParams));
+ fail("Bad request expected");
+ }
+ catch (PublicApiException e)
+ {
+ assertEquals(HttpStatus.SC_BAD_REQUEST, e.getHttpResponse().getStatusCode());
+ }
+ }
+
+
+ @Override
+ public String getScope()
+ {
+ return "public";
+ }
+}
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/tests/TestTypes.java b/remote-api/src/test/java/org/alfresco/rest/api/tests/TestTypes.java
new file mode 100644
index 0000000000..e8d4d59f59
--- /dev/null
+++ b/remote-api/src/test/java/org/alfresco/rest/api/tests/TestTypes.java
@@ -0,0 +1,238 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+
+package org.alfresco.rest.api.tests;
+
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.rest.api.tests.client.PublicApiClient;
+import org.alfresco.rest.api.tests.client.PublicApiException;
+import org.alfresco.rest.api.tests.client.RequestContext;
+import org.apache.commons.httpclient.HttpStatus;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+public class TestTypes extends AbstractBaseApiTest
+{
+
+ private PublicApiClient.Paging paging = getPaging(0, 10);
+ PublicApiClient.ListResponse types = null;
+ org.alfresco.rest.api.tests.client.data.Type type = null, whitePaperType = null, docType = null;
+ Map otherParams = new HashMap<>();
+
+ @Before
+ public void setup() throws Exception
+ {
+ super.setup();
+ whitePaperType = new org.alfresco.rest.api.tests.client.data.Type();
+ whitePaperType.setId("mycompany:whitepaper");
+ whitePaperType.setTitle("whitepaper");
+ whitePaperType.setDescription("Whitepaper");
+ whitePaperType.setParentId("mycompany:doc");
+
+ docType = new org.alfresco.rest.api.tests.client.data.Type();
+ docType.setId("mycompany:doc");
+ docType.setTitle("doc");
+ docType.setDescription("Doc");
+ docType.setParentId("cm:content");
+ }
+
+ @Test
+ public void testAllTypes() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ assertTrue(types.getPaging().getTotalItems() > 135);
+ assertTrue(types.getPaging().getHasMoreItems());
+
+ paging.setSkipCount(130);
+ paging.setMaxItems(50);
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ assertFalse(types.getPaging().getHasMoreItems());
+ }
+
+ @Test
+ public void filterTypesByNamespace() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ otherParams.put("where", "(namespaceUri matches('http://www.mycompany.com/model.*'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ types.getList().get(0).expected(docType);
+ types.getList().get(1).expected(whitePaperType);
+ assertEquals(types.getPaging().getTotalItems(), Integer.valueOf(2));
+
+ otherParams.put("where", "(not namespaceUri matches('http://www.mycompany.com/model.*'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ assertTrue(types.getPaging().getTotalItems() > 130);
+ }
+
+ @Test
+ public void filterTypesByParentId() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ otherParams.put("where", "(parentIds in ('cm:content'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ int total = types.getPaging().getTotalItems();
+
+ otherParams.put("where", "(parentIds in ('cm:content') AND namespaceUri matches('http://www.mycompany.com/model.*'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ types.getList().get(0).expected(docType);
+ types.getList().get(1).expected(whitePaperType);
+ assertEquals(types.getPaging().getTotalItems(), Integer.valueOf(2));
+
+ otherParams.put("where", "(parentIds in ('cm:content') AND not namespaceUri matches('http://www.mycompany.com/model.*'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ assertEquals(types.getPaging().getTotalItems(), Integer.valueOf(total - 2));
+
+ // match everything
+ otherParams.put("where", "(parentIds in ('cm:content') AND namespaceUri matches('.*'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ assertEquals(types.getPaging().getTotalItems(), Integer.valueOf(total));
+
+ // match nothing
+ otherParams.put("where", "(parentIds in ('cm:content') AND not namespaceUri matches('.*'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ assertEquals(types.getPaging().getTotalItems(), Integer.valueOf(0));
+ }
+
+ @Test
+ public void filterTypesByModelId() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ otherParams.put("where", "(modelIds in ('mycompany:model','test:scan'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ assertEquals(types.getPaging().getTotalItems(), Integer.valueOf(3));
+
+ otherParams.put("where", "(modelIds in ('mycompany:model','test:scan') AND namespaceUri matches('http://www.mycompany.com/model.*'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ types.getList().get(0).expected(docType);
+ types.getList().get(1).expected(whitePaperType);
+ assertEquals(types.getPaging().getTotalItems(), Integer.valueOf(2));
+
+ otherParams.put("where", "(modelIds in ('mycompany:model','test:scan') AND not namespaceUri matches('http://www.mycompany.com/model.*'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ assertEquals(types.getPaging().getTotalItems(), Integer.valueOf(1));
+
+ // match everything
+ otherParams.put("where", "(modelIds in ('mycompany:model','test:scan') AND namespaceUri matches('.*'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ assertEquals(types.getPaging().getTotalItems(), Integer.valueOf(3));
+
+ // match nothing
+ otherParams.put("where", "(modelIds in ('mycompany:model','test:scan') AND not namespaceUri matches('.*'))");
+ types = publicApiClient.types().getTypes(createParams(paging, otherParams));
+ assertEquals(types.getPaging().getTotalItems(), Integer.valueOf(0));
+ }
+
+ @Test
+ public void testTypesById() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ type = publicApiClient.types().getType("mycompany:whitepaper");
+ type.expected(whitePaperType);
+ }
+
+ @Test
+ public void testListTypeByInvalidValue() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ testListTypeException("(modelIds in ('mycompany:model','unknown:model'))");
+ testListTypeException("(modelIds in ('unknown:model','unknown1:another'))");
+ testListTypeException("(modelIds=' , , ')");
+ testListTypeException("(parentIds in ('cm:content','unknown:type')");
+ testListTypeException("(parentIds in ('unknown:type','cm:content'))");
+ testListTypeException("(parentIds in ('unknown:type','unknown:types'))");
+ testListTypeException("(parentIds in (' ',' ',' '))");
+ testListTypeException("");
+ testListTypeException("(namespaceUri matches('*'))"); // wrong pattern
+ }
+
+ @Test
+ public void testGetTypeByInvalidValue() throws PublicApiException
+ {
+ AuthenticationUtil.setRunAsUser(user1);
+ publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user1));
+
+ testGetTypeExceptions("unknown:childType");
+ testGetTypeExceptions("type:");
+ testGetTypeExceptions("type");
+ }
+
+
+ private void testGetTypeExceptions(String typeId)
+ {
+ try
+ {
+ publicApiClient.types().getType(typeId);
+ fail("type not found expected");
+ }
+ catch (PublicApiException e)
+ {
+ assertEquals(HttpStatus.SC_NOT_FOUND, e.getHttpResponse().getStatusCode());
+ }
+ }
+
+ private void testListTypeException(String query)
+ {
+ try
+ {
+ otherParams.put("where", query);
+ publicApiClient.types().getTypes(createParams(paging, otherParams));
+ fail("Bad request expected");
+ }
+ catch (PublicApiException e)
+ {
+ assertEquals(HttpStatus.SC_BAD_REQUEST, e.getHttpResponse().getStatusCode());
+ }
+ }
+
+
+ @Override
+ public String getScope()
+ {
+ return "public";
+ }
+}
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/tests/client/PublicApiClient.java b/remote-api/src/test/java/org/alfresco/rest/api/tests/client/PublicApiClient.java
index c72398ba15..836d21cee6 100644
--- a/remote-api/src/test/java/org/alfresco/rest/api/tests/client/PublicApiClient.java
+++ b/remote-api/src/test/java/org/alfresco/rest/api/tests/client/PublicApiClient.java
@@ -52,6 +52,7 @@ import org.alfresco.rest.api.tests.TestSites;
import org.alfresco.rest.api.tests.client.PublicApiHttpClient.BinaryPayload;
import org.alfresco.rest.api.tests.client.PublicApiHttpClient.RequestBuilder;
import org.alfresco.rest.api.tests.client.data.Action;
+import org.alfresco.rest.api.tests.client.data.Aspect;
import org.alfresco.rest.api.tests.client.data.Activities;
import org.alfresco.rest.api.tests.client.data.Activity;
import org.alfresco.rest.api.tests.client.data.AuditApp;
@@ -77,6 +78,7 @@ import org.alfresco.rest.api.tests.client.data.SiteMember;
import org.alfresco.rest.api.tests.client.data.SiteGroup;
import org.alfresco.rest.api.tests.client.data.SiteMembershipRequest;
import org.alfresco.rest.api.tests.client.data.Tag;
+import org.alfresco.rest.api.tests.client.data.Type;
import org.alfresco.rest.api.tests.util.RestApiUtil;
import org.apache.chemistry.opencmis.client.api.CmisObject;
import org.apache.chemistry.opencmis.client.api.Document;
@@ -133,7 +135,8 @@ public class PublicApiClient
private RawProxy rawProxy;
private AuditApps auditApps;
private Actions actions;
-
+ private Aspects aspects;
+ private Types types;
private ThreadLocal rc = new ThreadLocal();
private ObjectMapper objectMapper = new ObjectMapper();
@@ -159,6 +162,8 @@ public class PublicApiClient
rawProxy = new RawProxy();
auditApps = new AuditApps();
actions = new Actions();
+ aspects = new Aspects();
+ types = new Types();
}
public void setRequestContext(RequestContext rc)
@@ -234,7 +239,17 @@ public class PublicApiClient
{
return actions;
}
-
+
+ public Aspects aspects()
+ {
+ return aspects;
+ }
+
+ public Types types()
+ {
+ return types;
+ }
+
public CmisSession createPublicApiCMISSession(Binding binding, String version)
{
return createPublicApiCMISSession(binding, version, null);
@@ -1670,6 +1685,36 @@ public class PublicApiClient
}
}
+ public class Aspects extends AbstractProxy
+ {
+ public PublicApiClient.ListResponse getAspects(Map params) throws PublicApiException
+ {
+ HttpResponse response = getAll("aspects", null, null, null, params, "Failed to get aspects");
+ return Aspect.parseAspects(response.getJsonResponse());
+ }
+
+ public Aspect getAspect(String aspectId) throws PublicApiException
+ {
+ HttpResponse response = getAll("aspects", aspectId, null, null, null, "Failed to get aspect");
+ return Aspect.parseAspect((JSONObject)response.getJsonResponse().get("entry"));
+ }
+ }
+
+ public class Types extends AbstractProxy
+ {
+ public PublicApiClient.ListResponse getTypes(Map params) throws PublicApiException
+ {
+ HttpResponse response = getAll("types", null, null, null, params, "Failed to get types");
+ return Type.parseTypes(response.getJsonResponse());
+ }
+
+ public Type getType(String typeId) throws PublicApiException
+ {
+ HttpResponse response = getAll("types", typeId, null, null, null, "Failed to get type");
+ return Type.parseType((JSONObject)response.getJsonResponse().get("entry"));
+ }
+ }
+
public static class ExpectedPaging
{
private int skipCount;
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Aspect.java b/remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Aspect.java
new file mode 100644
index 0000000000..a1650bda16
--- /dev/null
+++ b/remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Aspect.java
@@ -0,0 +1,126 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rest.api.tests.client.data;
+
+import org.alfresco.rest.api.model.PropertyDefinition;
+import org.alfresco.rest.api.tests.client.PublicApiClient;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class Aspect extends org.alfresco.rest.api.model.Aspect implements Serializable, ExpectedComparison
+{
+
+ @Override
+ public void expected(Object model)
+ {
+ assertTrue("model is an instance of " + model.getClass(), model instanceof Aspect);
+
+ Aspect other = (Aspect) model;
+
+ AssertUtil.assertEquals("id", getId(), other.getId());
+ AssertUtil.assertEquals("title", getTitle(), other.getTitle());
+ AssertUtil.assertEquals("description", getDescription(), other.getDescription());
+ AssertUtil.assertEquals("parenId", getParentId(), other.getParentId());
+ }
+
+ @SuppressWarnings("unchecked")
+ public JSONObject toJSON()
+ {
+ JSONObject jsonObject = new JSONObject();
+ if (getId() != null)
+ {
+ jsonObject.put("id", getId());
+ }
+
+ jsonObject.put("title", getTitle());
+
+ if (getParentId() != null)
+ {
+ jsonObject.put("parentId", getParentId());
+ }
+
+ if (getDescription() != null)
+ {
+ jsonObject.put("description", getDescription());
+ }
+
+ if (getProperties() != null)
+ {
+ jsonObject.put("properties", getProperties());
+ }
+
+ return jsonObject;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Aspect parseAspect(JSONObject jsonObject)
+ {
+ String id = (String) jsonObject.get("id");
+ String title = (String) jsonObject.get("title");
+ String description = (String) jsonObject.get("description");
+ String parentId = (String) jsonObject.get("parentId");
+ List properties = (List) jsonObject.get("properties");
+
+ Aspect action = new Aspect();
+ action.setId(id);
+ action.setTitle(title);
+ action.setDescription(description);
+ action.setParentId(parentId);
+ action.setProperties(properties);
+
+ return action;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static PublicApiClient.ListResponse parseAspects(JSONObject jsonObject)
+ {
+ List aspects = new ArrayList();
+
+ JSONObject jsonList = (JSONObject)jsonObject.get("list");
+ assertNotNull(jsonList);
+
+ JSONArray jsonEntries = (JSONArray)jsonList.get("entries");
+ assertNotNull(jsonEntries);
+
+ for(int i = 0; i < jsonEntries.size(); i++)
+ {
+ JSONObject jsonEntry = (JSONObject)jsonEntries.get(i);
+ JSONObject entry = (JSONObject)jsonEntry.get("entry");
+ aspects.add(parseAspect(entry));
+ }
+
+ PublicApiClient.ExpectedPaging paging = PublicApiClient.ExpectedPaging.parsePagination(jsonList);
+ return new PublicApiClient.ListResponse(paging, aspects);
+ }
+
+}
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Node.java b/remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Node.java
index 91bd1cd73d..41cf597aad 100644
--- a/remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Node.java
+++ b/remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Node.java
@@ -27,7 +27,7 @@ package org.alfresco.rest.api.tests.client.data;
import org.alfresco.rest.api.model.AssocChild;
import org.alfresco.rest.api.model.AssocTarget;
-import org.alfresco.rest.api.model.NodeDefinition;
+import org.alfresco.rest.api.model.ClassDefinition;
import org.alfresco.rest.api.model.NodePermissions;
import java.util.Date;
@@ -80,7 +80,7 @@ public class Node
protected List allowableOperations;
protected NodePermissions nodePermissions;
- protected NodeDefinition definition;
+ protected ClassDefinition definition;
// please note: these are currently only used (optionally) for node create request
protected String relativePath;
@@ -325,12 +325,12 @@ public class Node
this.targets = targets;
}
- public NodeDefinition getDefinition()
+ public ClassDefinition getDefinition()
{
return definition;
}
- public void setDefinition(NodeDefinition definition)
+ public void setDefinition(ClassDefinition definition)
{
this.definition = definition;
}
diff --git a/remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Type.java b/remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Type.java
new file mode 100644
index 0000000000..68f77454c6
--- /dev/null
+++ b/remote-api/src/test/java/org/alfresco/rest/api/tests/client/data/Type.java
@@ -0,0 +1,126 @@
+/*
+ * #%L
+ * Alfresco Remote API
+ * %%
+ * Copyright (C) 2005 - 2021 Alfresco Software Limited
+ * %%
+ * This file is part of the Alfresco software.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ * #L%
+ */
+package org.alfresco.rest.api.tests.client.data;
+
+import org.alfresco.rest.api.model.PropertyDefinition;
+import org.alfresco.rest.api.tests.client.PublicApiClient;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class Type extends org.alfresco.rest.api.model.Type implements Serializable, ExpectedComparison
+{
+
+ @Override
+ public void expected(Object model)
+ {
+ assertTrue("model is an instance of " + model.getClass(), model instanceof Type);
+
+ Type other = (Type) model;
+
+ AssertUtil.assertEquals("id", getId(), other.getId());
+ AssertUtil.assertEquals("title", getTitle(), other.getTitle());
+ AssertUtil.assertEquals("description", getDescription(), other.getDescription());
+ AssertUtil.assertEquals("parenId", getParentId(), other.getParentId());
+ }
+
+ @SuppressWarnings("unchecked")
+ public JSONObject toJSON()
+ {
+ JSONObject jsonObject = new JSONObject();
+ if (getId() != null)
+ {
+ jsonObject.put("id", getId());
+ }
+
+ jsonObject.put("title", getTitle());
+
+ if (getParentId() != null)
+ {
+ jsonObject.put("parentId", getParentId());
+ }
+
+ if (getDescription() != null)
+ {
+ jsonObject.put("description", getDescription());
+ }
+
+ if (getProperties() != null)
+ {
+ jsonObject.put("properties", getProperties());
+ }
+
+ return jsonObject;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Type parseType(JSONObject jsonObject)
+ {
+ String id = (String) jsonObject.get("id");
+ String title = (String) jsonObject.get("title");
+ String description = (String) jsonObject.get("description");
+ String parentId = (String) jsonObject.get("parentId");
+ List properties = (List) jsonObject.get("properties");
+
+ Type action = new Type();
+ action.setId(id);
+ action.setTitle(title);
+ action.setDescription(description);
+ action.setParentId(parentId);
+ action.setProperties(properties);
+
+ return action;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static PublicApiClient.ListResponse parseTypes(JSONObject jsonObject)
+ {
+ List types = new ArrayList();
+
+ JSONObject jsonList = (JSONObject)jsonObject.get("list");
+ assertNotNull(jsonList);
+
+ JSONArray jsonEntries = (JSONArray)jsonList.get("entries");
+ assertNotNull(jsonEntries);
+
+ for(int i = 0; i < jsonEntries.size(); i++)
+ {
+ JSONObject jsonEntry = (JSONObject)jsonEntries.get(i);
+ JSONObject entry = (JSONObject)jsonEntry.get("entry");
+ types.add(parseType(entry));
+ }
+
+ PublicApiClient.ExpectedPaging paging = PublicApiClient.ExpectedPaging.parsePagination(jsonList);
+ return new PublicApiClient.ListResponse(paging, types);
+ }
+
+}
diff --git a/remote-api/src/test/resources/models/mycompany-model.xml b/remote-api/src/test/resources/models/mycompany-model.xml
new file mode 100644
index 0000000000..793e4082f2
--- /dev/null
+++ b/remote-api/src/test/resources/models/mycompany-model.xml
@@ -0,0 +1,147 @@
+
+ Administrator
+
+
+
+
+
+
+
+
+
+
+
+
+ doc
+ Doc
+ cm:content
+
+
+ d:text
+ false
+
+ TRUE
+ false
+
+
+
+ d:text
+ false
+
+ TRUE
+ false
+
+
+
+
+
+
+
+
+ whitepaper
+ Whitepaper
+ mycompany:doc
+
+
+
+
+
+
+
+
+
+
+ d:boolean
+ false
+ false
+
+ TRUE
+
+
+
+ d:date
+ false
+
+ TRUE
+
+
+
+
+
+
+
+
+ mycompany:active
+
+
+ d:int
+ false
+ 5
+
+ TRUE
+
+
+
+
+ 5
+
+
+ 23
+
+
+
+
+
+
+
+
+
+
+
+
+ Test Property
+ Property One Description
+ d:text
+ false
+
+ TRUE
+ false
+
+
+
+
+
+
+
+
+ Child Aspect
+ Child Aspect Description
+ smf:smartFolder
+
+
+ Propert One
+ Propert One Description
+ d:text
+ false
+
+ TRUE
+ false
+
+
+
+
+ 256
+
+
+ 5
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/remote-api/src/test/resources/models/test-scan.xml b/remote-api/src/test/resources/models/test-scan.xml
new file mode 100644
index 0000000000..20d163e941
--- /dev/null
+++ b/remote-api/src/test/resources/models/test-scan.xml
@@ -0,0 +1,84 @@
+
+
+ Administrator
+
+
+
+
+
+
+
+
+
+
+
+
+ cm:content
+
+
+ Description
+ Document knowledge from ai or OCR
+ d:mltext
+ false
+
+ TRUE
+ false
+
+
+
+ percent
+ Ocr scan percent
+ d:double
+ true
+
+ TRUE
+
+
+
+ Document Typt
+ Document type from OCR
+ d:text
+ false
+
+ TRUE
+ false
+
+
+
+
+
+
+
+
+
+
+ rescan
+ Doc that required to scan
+
+
+ rescanpercent
+ Rescan percent
+ d:text
+ false
+ 70
+
+ TRUE
+ false
+
+
+
+
+
+
+
+
+ Smart filter
+ Smart Filter
+ cm:auditable
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/remote-api/src/test/resources/rest-api-test-context.xml b/remote-api/src/test/resources/rest-api-test-context.xml
index 9e9a284cf4..293e169f48 100644
--- a/remote-api/src/test/resources/rest-api-test-context.xml
+++ b/remote-api/src/test/resources/rest-api-test-context.xml
@@ -16,6 +16,8 @@
models/custom-model.xml
models/bpmDelegateeModel.xml
models/people-api.xml
+ models/mycompany-model.xml
+ models/test-scan.xml