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
This commit is contained in:
dhrn
2021-02-05 15:25:22 +05:30
committed by GitHub
parent cc3c518940
commit 0211392ff6
35 changed files with 2325 additions and 198 deletions

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<Aspect> listAspects(Parameters params);
Aspect getAspectById(String aspectId);
}

View File

@@ -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);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<Type> listTypes(Parameters params);
Type getType(String aspectId);
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<Aspect>, EntityResourceAction.Read<Aspect>, InitializingBean
{
private Aspects aspects;
public void setAspects(Aspects aspects)
{
this.aspects = aspects;
}
@Override
public void afterPropertiesSet()
{
ParameterCheck.mandatory("aspects", this.aspects);
}
@Override
public CollectionWithPagingInfo<Aspect> readAll(Parameters params)
{
return aspects.listAspects(params);
}
@Override
public Aspect readById(String id, Parameters parameters)
{
return aspects.getAspectById(id);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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;

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<T extends AbstractClass> {
static String PARAM_MODEL_IDS = "modelIds";
static String PARAM_PARENT_IDS = "parentIds";
static String PARAM_NAMESPACE_URI = "namespaceUri";
public CollectionWithPagingInfo<T> createPagedResult(List<T> list, Paging paging)
{
int skipCount = paging.getSkipCount();
int maxItems = paging.getMaxItems();
int totalItems = list.size();
Collections.sort(list);
if (skipCount >= totalItems)
{
List<T> 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<String> 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<String> modelIds = null;
private Set<String> 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<String> getModelIds()
{
return this.modelIds;
}
public Set<String> getParentIds()
{
return this.parentIds;
}
public String getNotMatchedPrefix()
{
return this.notMatchedPrefix;
}
public String getMatchedPrefix()
{
return this.matchedPrefix;
}
}
public static class ModelApiFilter
{
private Set<String> modelIds;
private Set<String> parentIds;
private String matchedPrefix;
private String notMatchedPrefix;
public ModelApiFilter(Set<String> modelIds, Set<String> parentIds, String matchedPrefix, String notMatchedPrefix)
{
this.modelIds = modelIds;
this.parentIds = parentIds;
this.matchedPrefix = matchedPrefix;
this.notMatchedPrefix = notMatchedPrefix;
}
public Set<String> getModelIds()
{
return modelIds;
}
public String getMatchedPrefix()
{
return matchedPrefix;
}
public String getNotMatchedPrefix()
{
return notMatchedPrefix;
}
public Set<String> getParentIds()
{
return parentIds;
}
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<Aspect> 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<Aspect> listAspects(Parameters params)
{
Paging paging = params.getPaging();
ModelApiFilter query = getQuery(params.getQuery());
Stream<QName> 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<Aspect> 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<PropertyDefinition> properties = this.classDefinitionMapper.fromDictionaryClassDefinition(aspectDefinition, dictionaryService).getProperties();
return new Aspect(aspectDefinition, dictionaryService, properties);
}
private Collection<QName> 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<QName> getChildAspects(String aspectId)
{
Collection<QName> 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;
}
}

View File

@@ -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<String> EXCLUDED_NS = Arrays.asList(NamespaceService.SYSTEM_MODEL_1_0_URI);
private static final List<QName> 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 <NodeDefinitionProperty> getProperties(Map<QName, PropertyDefinition> propertiesMap, MessageLookup messageLookup)
private List <org.alfresco.rest.api.model.PropertyDefinition> getProperties(Map<QName, org.alfresco.service.cmr.dictionary.PropertyDefinition> 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<NodeDefinitionConstraint> getConstraints( Collection<ConstraintDefinition> constraintDefinitions,
MessageLookup messageLookup)
private List<org.alfresco.rest.api.model.ConstraintDefinition> getConstraints(Collection<org.alfresco.service.cmr.dictionary.ConstraintDefinition> 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;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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 <http://www.gnu.org/licenses/>.
* #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 extends AbstractClassModel> T updateTypeAspect(String modelName, T classDef, Parameters parameters)
private <T extends AbstractCustomClass> 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<String, CustomModelProperty> 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()))
{

View File

@@ -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));

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<Type> 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<Type> listTypes(Parameters params)
{
Paging paging = params.getPaging();
ModelApiFilter query = getQuery(params.getQuery());
Stream<QName> 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<Type> 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<PropertyDefinition> properties = this.classDefinitionMapper.fromDictionaryClassDefinition(typeDefinition, dictionaryService).getProperties();
return new Type(typeDefinition, dictionaryService, properties);
}
private Collection<QName> 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<QName> getChildTypes(String typeId)
{
Collection<QName> 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;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<AbstractClass>
{
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;
}
<T> List<T> setList(List<T> sourceList)
{
if (sourceList == null)
{
return Collections.<T> 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());
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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 <http://www.gnu.org/licenses/>.
* #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<CustomModelProperty> properties = Collections.emptyList();

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<PropertyDefinition> 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();
}
}

View File

@@ -31,17 +31,17 @@ import java.util.List;
*
* @author gfertuso
*/
public class NodeDefinition
public class ClassDefinition
{
List <NodeDefinitionProperty> properties;
List <PropertyDefinition> properties;
public List<NodeDefinitionProperty> getProperties()
public List<PropertyDefinition> getProperties()
{
return properties;
}
public void setProperties(List<NodeDefinitionProperty> properties)
public void setProperties(List<PropertyDefinition> properties)
{
this.properties = properties;
}

View File

@@ -31,7 +31,7 @@ import java.util.Map;
*
* @author gfertuso
*/
public class NodeDefinitionConstraint
public class ConstraintDefinition
{
private String id;
private String type;

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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 <http://www.gnu.org/licenses/>.
* #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()

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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 <http://www.gnu.org/licenses/>.
* #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()

View File

@@ -95,7 +95,7 @@ public class Node implements Comparable<Node>
protected List<String> 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<Node>
this.secondaryChildren = secondaryChildren;
}
public NodeDefinition getDefinition()
public ClassDefinition getDefinition()
{
return definition;
}
public void setDefinition(NodeDefinition definition)
public void setDefinition(ClassDefinition definition)
{
this.definition = definition;
}

View File

@@ -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<NodeDefinitionConstraint> constraints;
private List<ConstraintDefinition> constraints;
public String getId()
{
@@ -104,12 +104,12 @@ public class NodeDefinitionProperty
this.isProtected = isProtected;
}
public List<NodeDefinitionConstraint> getConstraints()
public List<ConstraintDefinition> getConstraints()
{
return constraints;
}
public void setConstraints(List<NodeDefinitionConstraint> constraints)
public void setConstraints(List<ConstraintDefinition> constraints)
{
this.constraints = constraints;
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<PropertyDefinition> 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();
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<Type>, EntityResourceAction.Read<Type>, InitializingBean
{
private Types types;
public void setTypes(Types types)
{
this.types = types;
}
@Override
public void afterPropertiesSet()
{
ParameterCheck.mandatory("types", this.types);
}
@Override
public CollectionWithPagingInfo<Type> readAll(Parameters params)
{
return types.listTypes(params);
}
@Override
public Type readById(String id, Parameters parameters)
{
return types.getType(id);
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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;

View File

@@ -530,7 +530,7 @@
</property>
</bean>
<bean id="nodeDefinitionMapper" class="org.alfresco.rest.api.impl.NodeDefinitionMapperImpl"/>
<bean id="classDefinitionMapper" class="org.alfresco.rest.api.impl.ClassDefinitionMapperImpl"/>
<bean id="nodes" class="org.alfresco.rest.api.impl.NodesImpl" init-method="init">
<property name="serviceRegistry" ref="ServiceRegistry"/>
@@ -542,7 +542,7 @@
<property name="personLookupProperties" ref="nodes.personLookupProperties"/>
<property name="poster" ref="activitiesPoster" />
<property name="smartStore" ref="smartStore"/>
<property name="nodeDefinitionMapper" ref="nodeDefinitionMapper" />
<property name="classDefinitionMapper" ref="classDefinitionMapper" />
</bean>
<bean id="Nodes" class="org.springframework.aop.framework.ProxyFactoryBean">
@@ -781,7 +781,7 @@
<bean id="siteSurfConfig" class="org.alfresco.rest.api.impl.SiteSurfConfig">
<property name="configPath" value="alfresco/bootstrap/site"/>
</bean>
<bean id="Sites" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.alfresco.rest.api.Sites</value>
@@ -1491,4 +1491,52 @@
<bean class="org.alfresco.rest.api.groups.SiteGroupsRelation">
<property name="sites" ref="Sites" />
</bean>
<bean class="org.alfresco.rest.api.aspects.AspectEntityResource">
<property name="aspects" ref="Aspects" />
</bean>
<bean id="aspects" class="org.alfresco.rest.api.impl.AspectsImpl">
<property name="dictionaryService" ref="DictionaryService" />
<property name="namespaceService" ref="namespaceService"/>
<property name="classDefinitionMapper" ref="classDefinitionMapper" />
</bean>
<bean id="Aspects" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.alfresco.rest.api.Aspects</value>
</property>
<property name="target">
<ref bean="aspects" />
</property>
<property name="interceptorNames">
<list>
<idref bean="legacyExceptionInterceptor" />
</list>
</property>
</bean>
<bean class="org.alfresco.rest.api.types.TypeEntityResource">
<property name="types" ref="Types" />
</bean>
<bean id="types" class="org.alfresco.rest.api.impl.TypesImpl">
<property name="dictionaryService" ref="DictionaryService" />
<property name="namespaceService" ref="namespaceService"/>
<property name="classDefinitionMapper" ref="classDefinitionMapper" />
</bean>
<bean id="Types" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.alfresco.rest.api.Types</value>
</property>
<property name="target">
<ref bean="types" />
</property>
<property name="interceptorNames">
<list>
<idref bean="legacyExceptionInterceptor" />
</list>
</property>
</bean>
</beans>

View File

@@ -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 extends AbstractClassModel> T createTypeAspect(Class<T> glazz, String modelName, String typeAspectName, String title, String desc,
String parent) throws Exception
protected <T extends AbstractCustomClass> T createTypeAspect(Class<T> 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<CustomModelProperty> expectedProps = expectedDetails.getProperties();
List<CustomModelProperty> actualProps = actualDetails.getProperties();

View File

@@ -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<NodeDefinitionProperty> properties)
private void checkDefinitionProperties(List<PropertyDefinition> 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<NodeDefinitionProperty> properties)
private void shouldNotContainSystemProperties(List<PropertyDefinition> 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<NodeDefinitionProperty> properties)
private void shouldContainParentProperties(List<PropertyDefinition> properties)
{
assertTrue(properties.stream()
.anyMatch(property ->
property.getId().equals("cm:name")));
}
private void shouldContainAspectProperties(List<NodeDefinitionProperty> properties)
private void shouldContainAspectProperties(List<PropertyDefinition> 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<NodeDefinitionConstraint> constraints)
private void checkPropertyConstraints(List<ConstraintDefinition> 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<String, Object> constraintParameters = nodeDefinitionConstraint.getParameters();
assertNotNull(constraintDefinition);
assertEquals("REGEX", constraintDefinition.getType());
Map<String, Object> 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"));

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<org.alfresco.rest.api.tests.client.data.Aspect> aspects = null;
org.alfresco.rest.api.tests.client.data.Aspect aspect, childAspect = null, smartFilter = null, rescanAspect = null;
Map<String, String> 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";
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<org.alfresco.rest.api.tests.client.data.Type> types = null;
org.alfresco.rest.api.tests.client.data.Type type = null, whitePaperType = null, docType = null;
Map<String, String> 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";
}
}

View File

@@ -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<RequestContext> rc = new ThreadLocal<RequestContext>();
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<Aspect> getAspects(Map<String, String> 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<Type> getTypes(Map<String, String> 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;

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<PropertyDefinition> properties = (List<PropertyDefinition>) 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<Aspect> parseAspects(JSONObject jsonObject)
{
List<Aspect> aspects = new ArrayList<Aspect>();
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<Aspect>(paging, aspects);
}
}

View File

@@ -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<String> 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;
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
* #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<PropertyDefinition> properties = (List<PropertyDefinition>) 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<Type> parseTypes(JSONObject jsonObject)
{
List<Type> types = new ArrayList<Type>();
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<Type>(paging, types);
}
}

View File

@@ -0,0 +1,147 @@
<model xmlns="http://www.alfresco.org/model/dictionary/1.0" name="mycompany:model">
<author>Administrator</author>
<imports>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
<import uri="http://www.alfresco.org/model/content/smartfolder/1.0" prefix="smf"/>
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
</imports>
<namespaces>
<namespace uri="http://www.mycompany.com/model/finance/1.0" prefix="mycompany"/>
</namespaces>
<data-types/>
<constraints/>
<types>
<type name="mycompany:doc">
<title>doc</title>
<description>Doc</description>
<parent>cm:content</parent>
<properties>
<property name="mycompany:description">
<type>d:text</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>TRUE</tokenised>
<facetable>false</facetable>
</index>
</property>
<property name="mycompany:title">
<type>d:text</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>TRUE</tokenised>
<facetable>false</facetable>
</index>
</property>
</properties>
<associations/>
<overrides/>
<mandatory-aspects/>
</type>
<type name="mycompany:whitepaper">
<title>whitepaper</title>
<description>Whitepaper</description>
<parent>mycompany:doc</parent>
<properties/>
<associations/>
<overrides/>
<mandatory-aspects/>
</type>
</types>
<aspects>
<aspect name="mycompany:active">
<properties>
<property name="mycompany:active">
<type>d:boolean</type>
<mandatory>false</mandatory>
<default>false</default>
<index enabled="true">
<tokenised>TRUE</tokenised>
</index>
</property>
<property name="mycompany:published">
<type>d:date</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>TRUE</tokenised>
</index>
</property>
</properties>
<associations/>
<overrides/>
<mandatory-aspects/>
</aspect>
<aspect name="mycompany:webable">
<parent>mycompany:active</parent>
<properties>
<property name="mycompany:count">
<type>d:int</type>
<mandatory>false</mandatory>
<default>5</default>
<index enabled="true">
<tokenised>TRUE</tokenised>
</index>
<constraints>
<constraint name="mycompany:MINMAX_b305ffc8-3488-4b4a-89bb-5d9c03da94fd" type="MINMAX">
<parameter name="minValue">
<value>5</value>
</parameter>
<parameter name="maxValue">
<value>23</value>
</parameter>
</constraint>
</constraints>
</property>
</properties>
<associations/>
<overrides/>
<mandatory-aspects/>
</aspect>
<aspect name="mycompany:testAspect">
<properties>
<property name="mycompany:testProperty">
<title>Test Property</title>
<description>Property One Description</description>
<type>d:text</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>TRUE</tokenised>
<facetable>false</facetable>
</index>
</property>
</properties>
<associations/>
<overrides/>
<mandatory-aspects/>
</aspect>
<aspect name="mycompany:childAspect">
<title>Child Aspect</title>
<description>Child Aspect Description</description>
<parent>smf:smartFolder</parent>
<properties>
<property name="mycompany:prop1">
<title>Propert One</title>
<description>Propert One Description</description>
<type>d:text</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>TRUE</tokenised>
<facetable>false</facetable>
</index>
<constraints>
<constraint name="mycompany:LENGTH_8befcbe6-52d2-438e-83f9-e255930bc664" type="LENGTH">
<parameter name="maxLength">
<value>256</value>
</parameter>
<parameter name="minLength">
<value>5</value>
</parameter>
</constraint>
</constraints>
</property>
</properties>
<associations/>
<overrides/>
<mandatory-aspects/>
</aspect>
</aspects>
</model>

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<model xmlns="http://www.alfresco.org/model/dictionary/1.0" name="test:scan">
<author>Administrator</author>
<imports>
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
<import uri="http://www.alfresco.org/model/content/smartfolder/1.0" prefix="smf"/>
</imports>
<namespaces>
<namespace uri="http://www.test.com/model/account/1.0" prefix="test"/>
</namespaces>
<data-types/>
<constraints/>
<types>
<type name="test:scanned">
<parent>cm:content</parent>
<properties>
<property name="test:description">
<title>Description</title>
<description>Document knowledge from ai or OCR</description>
<type>d:mltext</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>TRUE</tokenised>
<facetable>false</facetable>
</index>
</property>
<property name="test:percent">
<title>percent</title>
<description>Ocr scan percent</description>
<type>d:double</type>
<mandatory>true</mandatory>
<index enabled="false">
<tokenised>TRUE</tokenised>
</index>
</property>
<property name="test:doctype">
<title>Document Typt</title>
<description>Document type from OCR</description>
<type>d:text</type>
<mandatory>false</mandatory>
<index enabled="true">
<tokenised>TRUE</tokenised>
<facetable>false</facetable>
</index>
</property>
</properties>
<associations/>
<overrides/>
<mandatory-aspects/>
</type>
</types>
<aspects>
<aspect name="test:rescan">
<title>rescan</title>
<description>Doc that required to scan </description>
<properties>
<property name="test:rescanpercent">
<title>rescanpercent</title>
<description>Rescan percent</description>
<type>d:text</type>
<mandatory>false</mandatory>
<default>70</default>
<index enabled="true">
<tokenised>TRUE</tokenised>
<facetable>false</facetable>
</index>
</property>
</properties>
<associations/>
<overrides/>
<mandatory-aspects/>
</aspect>
<aspect name="test:smartFilter">
<title>Smart filter</title>
<description>Smart Filter</description>
<parent>cm:auditable</parent>
<properties/>
<associations/>
<overrides/>
<mandatory-aspects/>
</aspect>
</aspects>
</model>

View File

@@ -16,6 +16,8 @@
<value>models/custom-model.xml</value>
<value>models/bpmDelegateeModel.xml</value>
<value>models/people-api.xml</value>
<value>models/mycompany-model.xml</value>
<value>models/test-scan.xml</value>
</list>
</property>
</bean>