mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Allow management of Alfresco Aspects through CMIS REST and SOAP APIs
- In CMIS methods that allow setting of node properties, the <cmis:properties> element may carry an <alf:setAspects> extension that lists - aspectsToRemove - aspectsToAdd - properties (properties to set belonging to aspects rather than the node type) - In CMIS methods that allow retrieval of node properties, the <cmis:properties> carries an <alf:getAspects> extension that lists - appliedAspects - properties (properties belonging to aspects rather than the node type) - Added extension types to Alfresco-Core.xsd and referenced in extended WSDL - Plumbed in to Web Service and REST APIs git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19037 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -313,7 +313,6 @@
|
||||
<bean id="propertiesUtils" class="org.alfresco.repo.cmis.ws.utils.PropertyUtil">
|
||||
<property name="cmisDictionaryService" ref="CMISDictionaryService" />
|
||||
<property name="cmisService" ref="CMISService" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
<property name="dictionaryService" ref="DictionaryService" />
|
||||
<property name="namespaceService" ref="NamespaceService" />
|
||||
</bean>
|
||||
|
@@ -10,14 +10,33 @@
|
||||
</entry>
|
||||
[/#macro]
|
||||
|
||||
[#macro nodeCMISProps node propfilter]
|
||||
<cmis:properties>
|
||||
[@typeCMISProps node cmistype(node) propfilter/]
|
||||
[#-- Nest the Alfresco extension for aspects and their properties --]
|
||||
<alf:getAspects>
|
||||
[#list cmisaspects(node) as aspectdef]
|
||||
<alf:appliedAspects>${aspectdef.typeId.id}</alf:appliedAspects>
|
||||
[/#list]
|
||||
<alf:properties>
|
||||
[#list cmisaspects(node) as aspectdef]
|
||||
[@typeCMISProps node aspectdef propfilter/]
|
||||
[/#list]
|
||||
</alf:properties>
|
||||
</alf:getAspects>
|
||||
</cmis:properties>
|
||||
[/#macro]
|
||||
|
||||
[#macro objectCMISProps object propfilter]
|
||||
<cmis:properties>
|
||||
[#assign typedef = cmistype(object)]
|
||||
[@typeCMISProps object cmistype(object) propfilter/]
|
||||
</cmis:properties>
|
||||
[/#macro]
|
||||
|
||||
[#macro typeCMISProps object typedef propfilter]
|
||||
[#list typedef.propertyDefinitions?values as propdef]
|
||||
[@filter propfilter propdef.queryName][@prop object propdef/][/@filter]
|
||||
[/#list]
|
||||
</cmis:properties>
|
||||
[/#macro]
|
||||
|
||||
|
||||
@@ -42,7 +61,7 @@
|
||||
<app:edited>${xmldate(node.properties.modified)}</app:edited>
|
||||
<alf:icon>${absurl(url.context)}${node.icon16}</alf:icon>
|
||||
<cmisra:object>
|
||||
[@objectCMISProps node propfilter/]
|
||||
[@nodeCMISProps node propfilter/]
|
||||
[#if includeallowableactions][@allowableactions node/][/#if]
|
||||
[@relationships node includerelationships includeallowableactions propfilter/]
|
||||
[#if includeacl][@aclreport node/][/#if]
|
||||
@@ -95,7 +114,7 @@
|
||||
<app:edited>${xmldate(node.properties.modified)}</app:edited>
|
||||
<alf:icon>${absurl(url.context)}${node.icon16}</alf:icon>
|
||||
<cmisra:object>
|
||||
[@objectCMISProps node propfilter/]
|
||||
[@nodeCMISProps node propfilter/]
|
||||
[#if includeallowableactions][@allowableactions node/][/#if]
|
||||
[@relationships node includerelationships includeallowableactions propfilter/]
|
||||
[#if includeacl][@aclreport node/][/#if]
|
||||
|
@@ -89,76 +89,30 @@ function updateNode(node, entry, exclude, validator)
|
||||
|
||||
var updated = false;
|
||||
var object = entry.getExtension(atom.names.cmisra_object);
|
||||
var props = (object == null) ? null : object.properties;
|
||||
var vals = new Object();
|
||||
|
||||
// calculate list of properties to update
|
||||
// TODO: consider array form of properties.names
|
||||
var updateProps = (props == null) ? new Array() : props.ids.toArray().filter(function(element, index, array) {return true;});
|
||||
updateProps.push(PROP_NAME); // mapped to entry.title
|
||||
var exclude = (exclude == null) ? new Array() : exclude;
|
||||
exclude.push(PROP_BASE_TYPE_ID);
|
||||
updateProps = updateProps.filter(includeProperty, exclude);
|
||||
var typeDef = cmis.queryType(node);
|
||||
|
||||
// build values to update
|
||||
if (updateProps.length > 0)
|
||||
// Apply the provided properties of the node type
|
||||
unpackProperties(node, typeDef, object == null ? null : object.properties, exclude, validator, vals);
|
||||
|
||||
// NOTE: special case name: entry.title overrides cmis:name
|
||||
var propDef = typeDef.propertyDefinitions[PROP_NAME];
|
||||
vals[propDef.propertyAccessor.mappedProperty.toString()] = entry.title;
|
||||
|
||||
// Handle Alfresco aspects extension
|
||||
if (object != null)
|
||||
{
|
||||
var typeDef = cmis.queryType(node);
|
||||
var propDefs = typeDef.propertyDefinitions;
|
||||
for each (propName in updateProps)
|
||||
var extension = object.properties.getExtension(atom.names.alf_setAspects);
|
||||
|
||||
if (extension != null)
|
||||
{
|
||||
// is this a valid property?
|
||||
var propDef = propDefs[propName];
|
||||
if (propDef == null)
|
||||
{
|
||||
status.code = 400;
|
||||
status.message = "Property " + propName + " is not a known property for type " + typeDef.typeId;
|
||||
status.redirect = true;
|
||||
return null;
|
||||
}
|
||||
// Add and remove aspects
|
||||
cmis.setAspects(node, extension.aspectsToAdd, extension.aspectsToRemove);
|
||||
|
||||
// validate property update
|
||||
var valid = validator(propDef);
|
||||
if (valid == null)
|
||||
{
|
||||
// error, abort update
|
||||
return null;
|
||||
}
|
||||
if (valid == false)
|
||||
{
|
||||
// ignore property
|
||||
continue;
|
||||
}
|
||||
|
||||
// extract value
|
||||
var val = null;
|
||||
var prop = (props == null) ? null : props.find(propName);
|
||||
if (prop != null && !prop.isNull())
|
||||
{
|
||||
if (prop.isMultiValued())
|
||||
{
|
||||
if (propDef.updatability === CMISCardinalityEnum.MULTI_VALUED)
|
||||
{
|
||||
status.code = 500;
|
||||
status.message = "Property " + propName + " is single valued."
|
||||
status.redirect = true;
|
||||
return null;
|
||||
}
|
||||
val = prop.nativeValues;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = prop.nativeValue;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: special case name: entry.title overrides cmis:name
|
||||
if (propName === PROP_NAME)
|
||||
{
|
||||
val = entry.title;
|
||||
}
|
||||
|
||||
vals[propDef.propertyAccessor.mappedProperty.toString()] = val;
|
||||
// Apply the provided properties of the aspects
|
||||
unpackProperties(node, null, extension.properties, exclude, validator, vals);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,7 +189,81 @@ function updateNode(node, entry, exclude, validator)
|
||||
return updated;
|
||||
}
|
||||
|
||||
function unpackProperties(node, typeDef, props, exclude, validator, vals)
|
||||
{
|
||||
// calculate list of properties to update
|
||||
// TODO: consider array form of properties.names
|
||||
var updateProps = (props == null) ? new Array() : props.ids.toArray().filter(function(element, index, array) {return true;});
|
||||
updateProps = updateProps.filter(includeProperty, exclude);
|
||||
|
||||
// build values to update
|
||||
if (updateProps.length > 0)
|
||||
{
|
||||
for each (propName in updateProps)
|
||||
{
|
||||
// is this a valid property?
|
||||
var propDef = typeDef == null ? cmis.queryProperty(propName) : typeDef.propertyDefinitions[propName];
|
||||
if (propDef == null)
|
||||
{
|
||||
status.code = 400;
|
||||
if (typeDef == null)
|
||||
{
|
||||
status.message = "Property " + propName + " is not a known property";
|
||||
}
|
||||
else
|
||||
{
|
||||
status.message = "Property " + propName + " is not a known property for type " + typeDef.typeId;
|
||||
}
|
||||
status.redirect = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
// validate property update
|
||||
var valid = validator(propDef);
|
||||
if (valid == null)
|
||||
{
|
||||
// error, abort update
|
||||
return null;
|
||||
}
|
||||
if (valid == false)
|
||||
{
|
||||
// ignore property
|
||||
continue;
|
||||
}
|
||||
|
||||
// extract value
|
||||
var val = null;
|
||||
var prop = (props == null) ? null : props.find(propName);
|
||||
if (prop != null && !prop.isNull())
|
||||
{
|
||||
if (prop.isMultiValued())
|
||||
{
|
||||
if (propDef.updatability === CMISCardinalityEnum.MULTI_VALUED)
|
||||
{
|
||||
status.code = 500;
|
||||
status.message = "Property " + propName + " is single valued."
|
||||
status.redirect = true;
|
||||
return null;
|
||||
}
|
||||
val = prop.nativeValues;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = prop.nativeValue;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: special case name: entry.title overrides cmis:name
|
||||
if (propName === PROP_NAME)
|
||||
{
|
||||
val = entry.title;
|
||||
}
|
||||
|
||||
vals[propDef.propertyAccessor.mappedProperty.toString()] = val;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//
|
||||
// Create Alfresco Association from Atom Entry
|
||||
//
|
||||
|
@@ -174,6 +174,11 @@
|
||||
<constructor-arg><ref bean="webscripts.repo.imageresolver"/></constructor-arg>
|
||||
</bean>
|
||||
</entry>
|
||||
<entry key="cmisaspects">
|
||||
<bean class="org.alfresco.repo.cmis.rest.CMISAspectsMethod">
|
||||
<constructor-arg><ref bean="CMISService"/></constructor-arg>
|
||||
</bean>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
<property name="registryFactory">
|
||||
@@ -241,11 +246,12 @@
|
||||
<prop key="cmisra_object">{http://docs.oasis-open.org/ns/cmis/restatom/200908/}object</prop>
|
||||
<prop key="cmisra_content">{http://docs.oasis-open.org/ns/cmis/restatom/200908/}content</prop>
|
||||
<prop key="cmisra_repositoryInfo">{http://docs.oasis-open.org/ns/cmis/restatom/200908/}repositoryInfo</prop>
|
||||
<prop key="alf_setAspects">{http://www.alfresco.org}setAspects</prop>
|
||||
</props>
|
||||
</property>
|
||||
<property name="extensionFactories">
|
||||
<list>
|
||||
<bean class="org.apache.chemistry.abdera.ext.CMISExtensionFactory"/>
|
||||
<bean class="org.alfresco.repo.cmis.rest.AlfrescoCMISExtensionFactory"/>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
99
source/generated/org/alfresco/repo/cmis/ws/GetAspects.java
Normal file
99
source/generated/org/alfresco/repo/cmis/ws/GetAspects.java
Normal file
@@ -0,0 +1,99 @@
|
||||
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="appliedAspects" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* <element name="properties" type="{http://docs.oasis-open.org/ns/cmis/core/200908/}cmisPropertiesType" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"appliedAspects",
|
||||
"properties"
|
||||
})
|
||||
@XmlRootElement(name = "getAspects", namespace = "http://www.alfresco.org")
|
||||
public class GetAspects {
|
||||
|
||||
@XmlElement(namespace = "http://www.alfresco.org")
|
||||
protected List<String> appliedAspects;
|
||||
@XmlElement(namespace = "http://www.alfresco.org")
|
||||
protected CmisPropertiesType properties;
|
||||
|
||||
/**
|
||||
* Gets the value of the appliedAspects property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the appliedAspects property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getAppliedAspects().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link String }
|
||||
*
|
||||
*
|
||||
*/
|
||||
public List<String> getAppliedAspects() {
|
||||
if (appliedAspects == null) {
|
||||
appliedAspects = new ArrayList<String>();
|
||||
}
|
||||
return this.appliedAspects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the properties property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link CmisPropertiesType }
|
||||
*
|
||||
*/
|
||||
public CmisPropertiesType getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the properties property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link CmisPropertiesType }
|
||||
*
|
||||
*/
|
||||
public void setProperties(CmisPropertiesType value) {
|
||||
this.properties = value;
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
132
source/generated/org/alfresco/repo/cmis/ws/SetAspects.java
Normal file
132
source/generated/org/alfresco/repo/cmis/ws/SetAspects.java
Normal file
@@ -0,0 +1,132 @@
|
||||
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for anonymous complex type.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
*
|
||||
* <pre>
|
||||
* <complexType>
|
||||
* <complexContent>
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
|
||||
* <sequence>
|
||||
* <element name="aspectsToAdd" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* <element name="aspectsToRemove" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
|
||||
* <element name="properties" type="{http://docs.oasis-open.org/ns/cmis/core/200908/}cmisPropertiesType" minOccurs="0"/>
|
||||
* </sequence>
|
||||
* </restriction>
|
||||
* </complexContent>
|
||||
* </complexType>
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = {
|
||||
"aspectsToAdd",
|
||||
"aspectsToRemove",
|
||||
"properties"
|
||||
})
|
||||
@XmlRootElement(name = "setAspects", namespace = "http://www.alfresco.org")
|
||||
public class SetAspects {
|
||||
|
||||
@XmlElement(namespace = "http://www.alfresco.org")
|
||||
protected List<String> aspectsToAdd;
|
||||
@XmlElement(namespace = "http://www.alfresco.org")
|
||||
protected List<String> aspectsToRemove;
|
||||
@XmlElement(namespace = "http://www.alfresco.org")
|
||||
protected CmisPropertiesType properties;
|
||||
|
||||
/**
|
||||
* Gets the value of the aspectsToAdd property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the aspectsToAdd property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getAspectsToAdd().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link String }
|
||||
*
|
||||
*
|
||||
*/
|
||||
public List<String> getAspectsToAdd() {
|
||||
if (aspectsToAdd == null) {
|
||||
aspectsToAdd = new ArrayList<String>();
|
||||
}
|
||||
return this.aspectsToAdd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the aspectsToRemove property.
|
||||
*
|
||||
* <p>
|
||||
* This accessor method returns a reference to the live list,
|
||||
* not a snapshot. Therefore any modification you make to the
|
||||
* returned list will be present inside the JAXB object.
|
||||
* This is why there is not a <CODE>set</CODE> method for the aspectsToRemove property.
|
||||
*
|
||||
* <p>
|
||||
* For example, to add a new item, do as follows:
|
||||
* <pre>
|
||||
* getAspectsToRemove().add(newItem);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Objects of the following type(s) are allowed in the list
|
||||
* {@link String }
|
||||
*
|
||||
*
|
||||
*/
|
||||
public List<String> getAspectsToRemove() {
|
||||
if (aspectsToRemove == null) {
|
||||
aspectsToRemove = new ArrayList<String>();
|
||||
}
|
||||
return this.aspectsToRemove;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the properties property.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link CmisPropertiesType }
|
||||
*
|
||||
*/
|
||||
public CmisPropertiesType getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the properties property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link CmisPropertiesType }
|
||||
*
|
||||
*/
|
||||
public void setProperties(CmisPropertiesType value) {
|
||||
this.properties = value;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.cmis.rest;
|
||||
|
||||
import org.apache.chemistry.abdera.ext.CMISExtensionFactory;
|
||||
import org.apache.chemistry.abdera.ext.CMISProperties;
|
||||
|
||||
/**
|
||||
* A CMIS extension factory that is also aware of Alfresco extensions.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class AlfrescoCMISExtensionFactory extends CMISExtensionFactory
|
||||
{
|
||||
public AlfrescoCMISExtensionFactory()
|
||||
{
|
||||
super();
|
||||
addImpl(SetAspectsExtension.QNAME, SetAspectsExtension.class);
|
||||
addImpl(SetAspectsExtension.PROPERTIES, CMISProperties.class);
|
||||
}
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package org.alfresco.repo.cmis.rest;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.repo.template.TemplateNode;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
import freemarker.template.TemplateModelException;
|
||||
|
||||
/**
|
||||
* Custom FreeMarker Template language method.
|
||||
* <p>
|
||||
* Gets the type definitions of a TemplateNode's aspects
|
||||
* <p>
|
||||
* Usage: cmisaspects(TemplateNode node)
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class CMISAspectsMethod implements TemplateMethodModelEx
|
||||
{
|
||||
private CMISServices cmisService;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*/
|
||||
public CMISAspectsMethod(CMISServices cmisService)
|
||||
{
|
||||
this.cmisService = cmisService;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object exec(List args) throws TemplateModelException
|
||||
{
|
||||
NodeRef nodeRef = null;
|
||||
try
|
||||
{
|
||||
int i = 0;
|
||||
// extract node ref
|
||||
Object arg = args.get(i++);
|
||||
if (arg instanceof BeanModel)
|
||||
{
|
||||
Object wrapped = ((BeanModel) arg).getWrappedObject();
|
||||
if (wrapped != null)
|
||||
{
|
||||
if (wrapped instanceof TemplateNode)
|
||||
{
|
||||
nodeRef = ((TemplateNode) wrapped).getNodeRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfBoundsException e)
|
||||
{
|
||||
// Ignore optional arguments
|
||||
}
|
||||
|
||||
// query aspects
|
||||
if (nodeRef != null)
|
||||
{
|
||||
return cmisService.getAspects(nodeRef);
|
||||
}
|
||||
|
||||
return Collections.<CMISTypeDefinition> emptySet();
|
||||
}
|
||||
}
|
@@ -114,8 +114,8 @@ public class CMISPropertyValueMethod implements TemplateMethodModelEx
|
||||
Object result = null;
|
||||
if (wrapped != null && wrapped instanceof TemplateNode)
|
||||
{
|
||||
// retrieve property value from node
|
||||
result = cmisService.getProperty(((TemplateNode) wrapped).getNodeRef(), propertyName);
|
||||
// retrieve property value from node, allowing aspect properties
|
||||
result = cmisService.getProperty(((TemplateNode) wrapped).getNodeRef(), null, propertyName);
|
||||
}
|
||||
else if (wrapped != null && wrapped instanceof TemplateAssociation)
|
||||
{
|
||||
|
@@ -563,6 +563,30 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
return cmisDictionaryService.findProperty(propertyName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the aspects on a node (Alfresco extension).
|
||||
*
|
||||
* @param node
|
||||
* the node
|
||||
* @param aspectsToRemove
|
||||
* the aspects to remove
|
||||
* @param aspectsToAdd
|
||||
* the aspects to add
|
||||
* @throws WebScriptException
|
||||
* if an argument is invalid
|
||||
*/
|
||||
public void setAspects(ScriptNode node, Iterable<String> aspectsToRemove, Iterable<String> aspectsToAdd)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.setAspects(node.getNodeRef(), aspectsToRemove, aspectsToAdd);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SQL Query
|
||||
//
|
||||
|
120
source/java/org/alfresco/repo/cmis/rest/SetAspectsExtension.java
Normal file
120
source/java/org/alfresco/repo/cmis/rest/SetAspectsExtension.java
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package org.alfresco.repo.cmis.rest;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.apache.abdera.factory.Factory;
|
||||
import org.apache.abdera.model.Element;
|
||||
import org.apache.abdera.model.ExtensibleElementWrapper;
|
||||
import org.apache.chemistry.abdera.ext.CMISConstants;
|
||||
import org.apache.chemistry.abdera.ext.CMISProperties;
|
||||
|
||||
/**
|
||||
* Alfresco CMIS extension for controlling aspects and their properties.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class SetAspectsExtension extends ExtensibleElementWrapper
|
||||
{
|
||||
/** The Alfresco extension namespace. */
|
||||
private static final String NAMESPACE = "http://www.alfresco.org";
|
||||
|
||||
/** The name of this element. */
|
||||
public static final QName QNAME = new QName(NAMESPACE, "setAspects");
|
||||
|
||||
/** The name of the element containing the aspect properties. */
|
||||
public static final QName PROPERTIES = new QName(NAMESPACE, "properties");
|
||||
|
||||
/** The name of the element containing the aspects to add. */
|
||||
private static final QName ASPECTS_TO_ADD = new QName(NAMESPACE, "aspectsToAdd");
|
||||
|
||||
/** The name of the element containing the aspects to remove. */
|
||||
private static final QName ASPECTS_TO_REMOVE = new QName(NAMESPACE, "aspectsToRemove");
|
||||
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*
|
||||
* @param internal
|
||||
* the internal element
|
||||
*/
|
||||
public SetAspectsExtension(Element internal)
|
||||
{
|
||||
super(internal);
|
||||
}
|
||||
|
||||
/**
|
||||
* The Constructor.
|
||||
*
|
||||
* @param factory
|
||||
* the factory
|
||||
*/
|
||||
public SetAspectsExtension(Factory factory)
|
||||
{
|
||||
super(factory, CMISConstants.OBJECT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the aspects to add.
|
||||
*
|
||||
* @return the aspects to add
|
||||
*/
|
||||
public Set<String> getAspectsToAdd()
|
||||
{
|
||||
Set<String> aspects = new TreeSet<String>();
|
||||
for (Element aspect = getFirstChild(ASPECTS_TO_ADD); aspect != null; aspect = aspect
|
||||
.getNextSibling(ASPECTS_TO_ADD))
|
||||
{
|
||||
aspects.add(aspect.getText());
|
||||
|
||||
}
|
||||
return aspects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the aspects to remove.
|
||||
*
|
||||
* @return the aspects to remove
|
||||
*/
|
||||
public Set<String> getAspectsToRemove()
|
||||
{
|
||||
Set<String> aspects = new TreeSet<String>();
|
||||
for (Element aspect = getFirstChild(ASPECTS_TO_REMOVE); aspect != null; aspect = aspect
|
||||
.getNextSibling(ASPECTS_TO_REMOVE))
|
||||
{
|
||||
aspects.add(aspect.getText());
|
||||
|
||||
}
|
||||
return aspects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all aspect properties
|
||||
*
|
||||
* @return aspect properties
|
||||
*/
|
||||
public CMISProperties getProperties()
|
||||
{
|
||||
return (CMISProperties) getFirstChild(PROPERTIES);
|
||||
}
|
||||
}
|
@@ -45,7 +45,6 @@ import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||
@@ -213,14 +212,16 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
Map<String, Object> propertiesMap = propertiesUtil.getPropertiesMap(properties);
|
||||
String typeId = extractAndAssertTypeId(propertiesMap);
|
||||
CMISTypeDefinition type = cmisService.getTypeDefinition(typeId);
|
||||
TypeDefinition nativeType = dictionaryService.getType(nodeService.getType(folderNodeRef));
|
||||
if (type == null || type.getTypeId() == null || type.getTypeId().getScope() != CMISScope.FOLDER)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException("The typeID is not an Object-Type whose baseType is 'Folder': " + typeId, EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
|
||||
String name = propertiesUtil.getCmisPropertyValue(properties, CMISDictionaryModel.PROP_NAME, null);
|
||||
propertiesUtil.checkProperty(nativeType, type, CMISDictionaryModel.PROP_NAME, name, false);
|
||||
if (null == name)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException("Name property not found", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -819,8 +820,6 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
|
||||
{
|
||||
throw ExceptionUtil.createCmisException("Name property not found", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
propertiesUtil.checkProperty(null, typeDef, CMISDictionaryModel.PROP_NAME, result, (EnumVersioningState.CHECKEDOUT == versioningState));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -25,6 +25,7 @@ import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.datatype.DatatypeConfigurationException;
|
||||
@@ -37,9 +38,9 @@ import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISPropertyDefinition;
|
||||
import org.alfresco.cmis.CMISScope;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.cmis.CMISUpdatabilityEnum;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.CmisException;
|
||||
import org.alfresco.repo.cmis.ws.CmisPropertiesType;
|
||||
@@ -53,13 +54,13 @@ import org.alfresco.repo.cmis.ws.CmisPropertyInteger;
|
||||
import org.alfresco.repo.cmis.ws.CmisPropertyString;
|
||||
import org.alfresco.repo.cmis.ws.CmisPropertyUri;
|
||||
import org.alfresco.repo.cmis.ws.EnumServiceException;
|
||||
import org.alfresco.repo.cmis.ws.GetAspects;
|
||||
import org.alfresco.repo.cmis.ws.SetAspects;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -89,7 +90,6 @@ public class PropertyUtil
|
||||
|
||||
private static final String BASE_TYPE_PROPERTY_NAME = "BaseType";
|
||||
|
||||
private NodeService nodeService;
|
||||
private DictionaryService dictionaryService;
|
||||
private NamespaceService namespaceService;
|
||||
private CMISServices cmisService;
|
||||
@@ -99,11 +99,6 @@ public class PropertyUtil
|
||||
{
|
||||
}
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
@@ -348,59 +343,71 @@ public class PropertyUtil
|
||||
/**
|
||||
* Sets and checks all properties' fields for specified node
|
||||
*
|
||||
* @param nodeRef - <b>NodeRef</b> for node for those properties must be setted
|
||||
* @param properties - <b>CmisPropertiesType</b> instance that contains all the necessary properties' fields
|
||||
* @param ignoringPropertiesFilter - <b>PropertyFilter</b> instance. This filter determines which properties should be ignored and not setted without exception. If this
|
||||
* parameter is <b>null</b> all properties will be processed in common flow
|
||||
* @param nodeRef
|
||||
* - <b>NodeRef</b> for node for those properties must be setted
|
||||
* @param properties
|
||||
* - <b>CmisPropertiesType</b> instance that contains all the necessary properties' fields
|
||||
* @param ignoringPropertiesFilter
|
||||
* - <b>PropertyFilter</b> instance. This filter determines which properties should be ignored and not
|
||||
* setted without exception. If this parameter is <b>null</b> all properties will be processed in common
|
||||
* flow
|
||||
*/
|
||||
public void setProperties(NodeRef nodeRef, CmisPropertiesType properties, PropertyFilter ignoringPropertiesFilter) throws CmisException
|
||||
public void setProperties(NodeRef nodeRef, CmisPropertiesType properties, PropertyFilter ignoringPropertiesFilter)
|
||||
throws CmisException
|
||||
{
|
||||
// TODO: WARINING!!! This is WRONG behavior!!! Each CMIS object type and each property MUST be described in appropriate to CMIS manner
|
||||
if ((null == nodeRef) || (null == properties) || (null == properties.getProperty()))
|
||||
if (nodeRef == null || properties == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String typeId = getProperty(nodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, null);
|
||||
boolean checkedOut = getProperty(nodeRef, CMISDictionaryModel.PROP_IS_VERSION_SERIES_CHECKED_OUT, false);
|
||||
CMISTypeDefinition cmisObjectType = cmisDictionaryService.findType(typeId);
|
||||
|
||||
TypeDefinition nativeObjectType = dictionaryService.getType(nodeService.getType(nodeRef));
|
||||
|
||||
if ((null == cmisObjectType) && (null == nativeObjectType))
|
||||
try
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(("Can't find type definition for current object with \"" + typeId + "\" type Id"), EnumServiceException.INVALID_ARGUMENT);
|
||||
|
||||
for (CmisProperty property : properties.getProperty())
|
||||
{
|
||||
String propertyName = getPropertyName(property);
|
||||
if ((null == propertyName)
|
||||
|| ((null != ignoringPropertiesFilter) && ignoringPropertiesFilter.allow(propertyName)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Object value = getValue(property);
|
||||
cmisService.setProperty(nodeRef, propertyName, (Serializable) value);
|
||||
}
|
||||
|
||||
// Process Alfresco aspect-setting extension
|
||||
for (Object extensionObj : properties.getAny())
|
||||
{
|
||||
if (!(extensionObj instanceof SetAspects))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
SetAspects setAspects = (SetAspects) extensionObj;
|
||||
cmisService.setAspects(nodeRef, setAspects.getAspectsToRemove(), setAspects.getAspectsToAdd());
|
||||
CmisPropertiesType extensionProperties = setAspects.getProperties();
|
||||
if (extensionProperties == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (CmisProperty property : extensionProperties.getProperty())
|
||||
{
|
||||
String propertyName = getPropertyName(property);
|
||||
if ((null == propertyName)
|
||||
|| ((null != ignoringPropertiesFilter) && ignoringPropertiesFilter.allow(propertyName)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Object value = getValue(property);
|
||||
|
||||
// This time, call setProperty without constraining the owning type
|
||||
cmisService.setProperty(nodeRef, null, propertyName, (Serializable) value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (CmisProperty property : properties.getProperty())
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
String propertyName = getPropertyName(property);
|
||||
if ((null == propertyName) || ((null != ignoringPropertiesFilter) && ignoringPropertiesFilter.allow(propertyName)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Object value = getValue(property);
|
||||
QName alfrescoPropertyName = null;
|
||||
switch (checkProperty(nativeObjectType, cmisObjectType, propertyName, value, checkedOut))
|
||||
{
|
||||
case PROPERTY_CHECKED:
|
||||
{
|
||||
alfrescoPropertyName = cmisDictionaryService.findProperty(propertyName, cmisObjectType).getPropertyAccessor().getMappedProperty();
|
||||
break;
|
||||
}
|
||||
case PROPERTY_NATIVE:
|
||||
{
|
||||
alfrescoPropertyName = createQName(propertyName);
|
||||
break;
|
||||
}
|
||||
case PROPERTY_NOT_UPDATABLE:
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(("\"" + propertyName + "\" property is not updatable by repository for specified Object id"),
|
||||
EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
}
|
||||
nodeService.setProperty(nodeRef, alfrescoPropertyName, (Serializable) value);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,82 +439,6 @@ public class PropertyUtil
|
||||
return qname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks any CMIS property on constraints conforming
|
||||
*
|
||||
* @param type - <b>CMISTypeDefinition</b> instance. This value must not be <b>null</b>
|
||||
* @param propertyName - <b>String</b> instance that represents name of the property
|
||||
* @param value - instance of a <b>Serializable</b> object that represents value of the property
|
||||
* @return <b>true</b> if property was checked and <b>false</b> if property can't be checked
|
||||
* @throws <b>CmisException</b> if some constraint is not satisfied
|
||||
*/
|
||||
public PropertyCheckingStateEnum checkProperty(TypeDefinition nativeObjectType, CMISTypeDefinition cmisObjectType, String propertyName, Object value, boolean checkedOut)
|
||||
throws CmisException
|
||||
{
|
||||
CMISPropertyDefinition propertyDefinition = cmisDictionaryService.findProperty(propertyName, cmisObjectType);
|
||||
|
||||
if (null == propertyDefinition)
|
||||
{
|
||||
// TODO: WARINING!!! This is WRONG behavior!!! Each CMIS object type and each property MUST be described in appropriate CMIS manner
|
||||
QName qualifiedName = createQName(propertyName);
|
||||
Map<QName, PropertyDefinition> properties = (null != nativeObjectType) ? (nativeObjectType.getProperties()) : (null);
|
||||
if ((null == qualifiedName) || (null == properties) || properties.containsKey(qualifiedName))
|
||||
{
|
||||
return PropertyCheckingStateEnum.PROPERTY_NOT_UPDATABLE;
|
||||
}
|
||||
return PropertyCheckingStateEnum.PROPERTY_NATIVE;
|
||||
}
|
||||
|
||||
// [FIXED BUG] condition and first calculating value were swapped
|
||||
boolean updatable = ((CMISUpdatabilityEnum.READ_AND_WRITE_WHEN_CHECKED_OUT == propertyDefinition.getUpdatability()) ? (checkedOut)
|
||||
: (CMISUpdatabilityEnum.READ_AND_WRITE == propertyDefinition.getUpdatability()));
|
||||
|
||||
if (!updatable)
|
||||
{
|
||||
return PropertyCheckingStateEnum.PROPERTY_NOT_UPDATABLE;
|
||||
}
|
||||
|
||||
if (propertyDefinition.isRequired() && (null == value))
|
||||
{
|
||||
throw ExceptionUtil.createCmisException((propertyName + " property required"), EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
|
||||
switch (propertyDefinition.getDataType())
|
||||
{
|
||||
case STRING:
|
||||
{
|
||||
checkStringProperty(propertyDefinition, propertyName, (String) value);
|
||||
break;
|
||||
}
|
||||
case INTEGER:
|
||||
case DECIMAL:
|
||||
{
|
||||
checkNumberProperty(propertyDefinition, propertyName, (Number) value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return PropertyCheckingStateEnum.PROPERTY_CHECKED;
|
||||
}
|
||||
|
||||
public enum PropertyCheckingStateEnum
|
||||
{
|
||||
PROPERTY_CHECKED, PROPERTY_NATIVE, PROPERTY_NOT_UPDATABLE;
|
||||
}
|
||||
|
||||
private void checkNumberProperty(CMISPropertyDefinition propertyDefinition, String propertyName, Number value)
|
||||
{
|
||||
// TODO: if max and min value properties will be added to CMISPropertyDefinition
|
||||
}
|
||||
|
||||
private void checkStringProperty(CMISPropertyDefinition propertyDefinition, String propertyName, String value) throws CmisException
|
||||
{
|
||||
if (value != null && (propertyDefinition.getMaximumLength() > 0) && (value.length() > propertyDefinition.getMaximumLength()))
|
||||
{
|
||||
throw ExceptionUtil.createCmisException((propertyName + " property value is too long"), EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CMIS properties for object
|
||||
*
|
||||
@@ -517,23 +448,36 @@ public class PropertyUtil
|
||||
*/
|
||||
public CmisPropertiesType getProperties(Object object, PropertyFilter filter) throws CmisException
|
||||
{
|
||||
if (object instanceof Version)
|
||||
{
|
||||
object = ((Version) object).getFrozenStateNodeRef();
|
||||
}
|
||||
try
|
||||
{
|
||||
CmisPropertiesType result = new CmisPropertiesType();
|
||||
Map<String, Serializable> properties;
|
||||
if (object instanceof NodeRef)
|
||||
{
|
||||
properties = cmisService.getProperties((NodeRef) object);
|
||||
}
|
||||
else if (object instanceof Version)
|
||||
{
|
||||
properties = cmisService.getProperties(((Version) object).getFrozenStateNodeRef());
|
||||
|
||||
// Handle fetching of aspects and their properties with Alfresco extension
|
||||
GetAspects extension = new GetAspects();
|
||||
result.getAny().add(extension);
|
||||
List<String> aspects = extension.getAppliedAspects();
|
||||
Map<String, Serializable> aspectProperties = new HashMap<String, Serializable>(97);
|
||||
for (CMISTypeDefinition typeDef : cmisService.getAspects((NodeRef)object))
|
||||
{
|
||||
aspects.add(typeDef.getTypeId().getId());
|
||||
aspectProperties.putAll(cmisService.getProperties((NodeRef)object, typeDef));
|
||||
}
|
||||
CmisPropertiesType aspectResult = new CmisPropertiesType();
|
||||
convertToCmisProperties(aspectProperties, filter, aspectResult);
|
||||
extension.setProperties(aspectResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
properties = createBaseRelationshipProperties((AssociationRef) object);
|
||||
}
|
||||
|
||||
CmisPropertiesType result = new CmisPropertiesType();
|
||||
convertToCmisProperties(properties, filter, result);
|
||||
return result;
|
||||
}
|
||||
|
9
source/wsdl/Alfresco-CMISWS-Service.wsdl
Normal file
9
source/wsdl/Alfresco-CMISWS-Service.wsdl
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns:alf="http://www.alfresco.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||
xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:ns="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://www.alfresco.org"
|
||||
name="AlfrescoCMISWebServices">
|
||||
|
||||
<import namespace="http://docs.oasis-open.org/ns/cmis/ws/200908/" location="CMISWS-Service.wsdl" />
|
||||
<import namespace="http://www.alfresco.org" location="Alfresco-Core.xsd" />
|
||||
|
||||
</definitions>
|
28
source/wsdl/Alfresco-Core.xsd
Normal file
28
source/wsdl/Alfresco-Core.xsd
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.alfresco.org"
|
||||
xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
|
||||
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc" jaxb:version="2.1"
|
||||
xmlns:cmis="http://docs.oasis-open.org/ns/cmis/core/200908/" version="1.0">
|
||||
|
||||
<xs:import schemaLocation="CMIS-Core.xsd" namespace="http://docs.oasis-open.org/ns/cmis/core/200908/" />
|
||||
|
||||
<xs:element name="setAspects">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element minOccurs="0" maxOccurs="unbounded" name="aspectsToAdd" type="xs:string" />
|
||||
<xs:element minOccurs="0" maxOccurs="unbounded" name="aspectsToRemove" type="xs:string" />
|
||||
<xs:element name="properties" type="cmis:cmisPropertiesType" minOccurs="0" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="getAspects">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element minOccurs="0" maxOccurs="unbounded" name="appliedAspects" type="xs:string" />
|
||||
<xs:element name="properties" type="cmis:cmisPropertiesType" minOccurs="0" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
</xs:schema>
|
Reference in New Issue
Block a user