mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merging BRANCHES/DEV/CMIS_10 to HEAD (phase 2 - currently up-to-date with branch):
18717: SAIL-166: Refactor CMIS to use shared services and resolve objectIds and error codes consistently 18731: SAIL-169: CMIS REST versioning compliance 18732: Fix failing change log test. 18768: Add displayName and queryName attributes to rendered properties (in CMIS AtomPub binding). 18775: Fix exception reporting when retrieving items that do not exist (in CMIS AtomPub binding). 18784: Fix CMIS REST change logging 18785: SAIL-174: CMIS Relationship lookup by association ID 18812: SAIL-183: Support orderBy argument for getChildren and getCheckedOutDocs in CMIS REST and Web Service bindings 18823: CMIS WS Bindings were moved to 1.0 cd07 schema. 18838: Update to latest Chemistry TCK. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18847 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.repo.cmis.ws.CmisException;
|
||||
import org.alfresco.repo.cmis.ws.EnumServiceException;
|
||||
import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
|
||||
/**
|
||||
* Property filter supporting CMIS filter expression
|
||||
@@ -56,11 +56,11 @@ public class PropertyFilter
|
||||
* @param filter filter value (case insensitive)
|
||||
* @throws FilterNotValidException if filter string isn't valid
|
||||
*/
|
||||
public PropertyFilter(String filter, CmisObjectsUtils cmisObjectsUtils) throws CmisException
|
||||
public PropertyFilter(String filter) throws CmisException
|
||||
{
|
||||
if (filter == null || filter.length() < MINIMAL_ALLOWED_STRUCTURE_SIZE ? false : !PROPERTY_FILTER_REGEX.matcher(filter).matches())
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("\"" + filter + "\" filter value is invalid"), EnumServiceException.FILTER_NOT_VALID);
|
||||
throw ExceptionUtil.createCmisException(("\"" + filter + "\" filter value is invalid"), EnumServiceException.FILTER_NOT_VALID);
|
||||
}
|
||||
|
||||
if (!filter.equals(MATCH_ALL_FILTER) && filter.length() >= MINIMAL_ALLOWED_STRUCTURE_SIZE)
|
||||
|
@@ -28,7 +28,6 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.repo.cmis.ws.CmisException;
|
||||
import org.alfresco.repo.cmis.ws.EnumServiceException;
|
||||
import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
@@ -59,23 +58,21 @@ public class PropertyFilterTest extends TestCase
|
||||
private static final String INVALID_FILTER_WITH_DENIED_SYMBOL = "ObjectId; name";
|
||||
private static final String INVALID_FILTER_WITH_LAST_INVALID_SYMBOL = "ObjectId, name*";
|
||||
|
||||
private CmisObjectsUtils cmisObjectsUtils = new CmisObjectsUtils();
|
||||
|
||||
public void testValidFilters() throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
allTokensValidAssertion(new PropertyFilter());
|
||||
allTokensValidAssertion(new PropertyFilter(VALID_MATCHE_ALL_EMPTY_FILTER, cmisObjectsUtils));
|
||||
allTokensValidAssertion(new PropertyFilter(VALID_MATCHE_ALL_FILTER, cmisObjectsUtils));
|
||||
allTokensValidAssertion(new PropertyFilter(VALID_MATCHE_ALL_EMPTY_FILTER));
|
||||
allTokensValidAssertion(new PropertyFilter(VALID_MATCHE_ALL_FILTER));
|
||||
|
||||
onlyNameTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_NAME, cmisObjectsUtils));
|
||||
onlyNameTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_NAME));
|
||||
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS, cmisObjectsUtils));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(LONG_VALID_FILTER_WITH_SEVERAL_TOKENS, cmisObjectsUtils));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_WITHOUT_BREAKS, cmisObjectsUtils));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_BREAKS_IN_SOME_PLACES, cmisObjectsUtils));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_SEVERAL_BREAKS_IN_SOME_PLACES, cmisObjectsUtils));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(LONG_VALID_FILTER_WITH_SEVERAL_TOKENS));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_WITHOUT_BREAKS));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_BREAKS_IN_SOME_PLACES));
|
||||
nameAndObjectIdTokensAssertionValid(new PropertyFilter(VALID_FILTER_WITH_SEVERAL_TOKENS_AND_WITH_SEVERAL_BREAKS_IN_SOME_PLACES));
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
@@ -144,7 +141,7 @@ public class PropertyFilterTest extends TestCase
|
||||
{
|
||||
try
|
||||
{
|
||||
new PropertyFilter(filterValue, cmisObjectsUtils);
|
||||
new PropertyFilter(filterValue);
|
||||
|
||||
fail("Invalid filter \"" + filterValue + "\" was interpreted as valid");
|
||||
}
|
||||
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
|
||||
/**
|
||||
* AVM Path Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class AVMPathReference extends ObjectPathReference
|
||||
{
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param repo
|
||||
* @param path
|
||||
*/
|
||||
public AVMPathReference(CMISServices cmisServices, CMISRepositoryReference repo, String path)
|
||||
{
|
||||
super(cmisServices, repo, path);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.reference.ObjectPathReference#getNodeRef()
|
||||
*/
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return cmisServices.getNode("avmpath", reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "AVMPathReference[storeRef=" + repo.getStoreRef() + ",path=" + path + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract Object Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public abstract class AbstractObjectReference implements CMISObjectReference
|
||||
{
|
||||
protected CMISServices cmisServices;
|
||||
protected CMISRepositoryReference repo;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param repo
|
||||
*/
|
||||
public AbstractObjectReference(CMISServices cmisServices, CMISRepositoryReference repo)
|
||||
{
|
||||
this.cmisServices = cmisServices;
|
||||
this.repo = repo;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getRepositoryReference()
|
||||
*/
|
||||
public CMISRepositoryReference getRepositoryReference()
|
||||
{
|
||||
return repo;
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract Repository Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public abstract class AbstractRepositoryReference implements CMISRepositoryReference
|
||||
{
|
||||
protected CMISServices cmisServices;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
*/
|
||||
public AbstractRepositoryReference(CMISServices cmisServices)
|
||||
{
|
||||
this.cmisServices = cmisServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getStoreRef().toString();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRelationshipReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
/**
|
||||
* Association ID relationship reference. An association ID can be resolved to an {@link AssociationRef}.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class AssociationIdRelationshipReference implements CMISRelationshipReference
|
||||
{
|
||||
private CMISServices cmisServices;
|
||||
private String assocId;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param assocId
|
||||
*/
|
||||
public AssociationIdRelationshipReference(CMISServices cmisServices, String assocId)
|
||||
{
|
||||
this.cmisServices = cmisServices;
|
||||
this.assocId = assocId;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISRelationshipReference#getAssocRef()
|
||||
*/
|
||||
public AssociationRef getAssocRef()
|
||||
{
|
||||
try
|
||||
{
|
||||
return cmisServices.getReadableObject(CMISServices.ASSOC_ID_PREFIX + this.assocId, AssociationRef.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getRepositoryReference()
|
||||
*/
|
||||
public CMISRepositoryReference getRepositoryReference()
|
||||
{
|
||||
return new AbstractRepositoryReference(cmisServices)
|
||||
{
|
||||
public StoreRef getStoreRef()
|
||||
{
|
||||
return getAssocRef().getSourceRef().getStoreRef();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "AssociationIdRelationshipReference[assocId=" + this.assocId + "]";
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
|
||||
/**
|
||||
* Default Repository Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class DefaultRepositoryReference extends AbstractRepositoryReference
|
||||
{
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
*/
|
||||
public DefaultRepositoryReference(CMISServices cmisServices)
|
||||
{
|
||||
super(cmisServices);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISRepositoryReference#getStoreRef()
|
||||
*/
|
||||
public StoreRef getStoreRef()
|
||||
{
|
||||
return cmisServices.getDefaultRootStoreRef();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
/**
|
||||
* GUID Object Reference. This class decodes node 'paths' generated by links.lib.atom.ftl. These are not the same as
|
||||
* CMIS object IDs.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class NodeIdReference extends AbstractObjectReference
|
||||
{
|
||||
private String id;
|
||||
private String[] reference;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param repo
|
||||
* @param id
|
||||
*/
|
||||
public NodeIdReference(CMISServices cmisServices, CMISRepositoryReference repo, String id)
|
||||
{
|
||||
super(cmisServices, repo);
|
||||
|
||||
this.id = id;
|
||||
|
||||
StoreRef storeRef = repo.getStoreRef();
|
||||
String[] idParts = this.id.split("/");
|
||||
reference = new String[2 + idParts.length];
|
||||
reference[0] = storeRef.getProtocol();
|
||||
reference[1] = storeRef.getIdentifier();
|
||||
System.arraycopy(idParts, 0, reference, 2, idParts.length);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getNodeRef()
|
||||
*/
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return cmisServices.getNode("node", reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return id
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "NodeIdReference[storeRef=" + repo.getStoreRef() + ",id=" + id + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
/**
|
||||
* CMIS Object ID reference. A CMIS object ID encapsulates both a store and a node and identifies a specific version.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class ObjectIdReference implements CMISObjectReference
|
||||
{
|
||||
private CMISServices cmisServices;
|
||||
private String objectId;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param storeRef
|
||||
*/
|
||||
public ObjectIdReference(CMISServices cmisServices, String objectId)
|
||||
{
|
||||
this.cmisServices = cmisServices;
|
||||
this.objectId = objectId;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getNodeRef()
|
||||
*/
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
try
|
||||
{
|
||||
return cmisServices.getReadableObject(this.objectId, NodeRef.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getRepositoryReference()
|
||||
*/
|
||||
public CMISRepositoryReference getRepositoryReference()
|
||||
{
|
||||
return new AbstractRepositoryReference(cmisServices)
|
||||
{
|
||||
public StoreRef getStoreRef()
|
||||
{
|
||||
return getNodeRef().getStoreRef();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "ObjectIdReference[objectId=" + this.objectId + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
|
||||
/**
|
||||
* Path Object Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class ObjectPathReference extends AbstractObjectReference
|
||||
{
|
||||
protected String path;
|
||||
protected String[] reference;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param repo
|
||||
* @param path
|
||||
*/
|
||||
public ObjectPathReference(CMISServices cmisServices, CMISRepositoryReference repo, String path)
|
||||
{
|
||||
super(cmisServices, repo);
|
||||
this.path = path.startsWith("/") ? path : "/" + path;
|
||||
this.path = (!cmisServices.getDefaultRootPath().equals("/")) ? cmisServices.getDefaultRootPath() + this.path : this.path;
|
||||
String[] splitPath = this.path.split("/");
|
||||
String[] pathSegments = new String[splitPath.length -1];
|
||||
System.arraycopy(splitPath, 1, pathSegments, 0, splitPath.length -1);
|
||||
this.reference = new String[2 + pathSegments.length];
|
||||
StoreRef storeRef = repo.getStoreRef();
|
||||
reference[0] = storeRef.getProtocol();
|
||||
reference[1] = storeRef.getIdentifier();
|
||||
System.arraycopy(pathSegments, 0, reference, 2, pathSegments.length);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISObjectReference#getNodeRef()
|
||||
*/
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return cmisServices.getNode("path", reference);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return path
|
||||
*/
|
||||
public String getPath()
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "ObjectPathReference[storeRef=" + repo.getStoreRef() + ",path=" + path + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.CMISRelationshipReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
|
||||
|
||||
/**
|
||||
* Reference Factory
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class ReferenceFactory
|
||||
{
|
||||
private CMISServices cmisService;
|
||||
|
||||
/**
|
||||
* @param cmisService
|
||||
*/
|
||||
public void setCMISService(CMISServices cmisService)
|
||||
{
|
||||
this.cmisService = cmisService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create CMIS Repository Reference from URL segments
|
||||
*
|
||||
* @param args url arguments
|
||||
* @param templateArgs url template arguments
|
||||
* @return Repository Reference (or null, in case of bad url)
|
||||
*/
|
||||
public CMISRepositoryReference createRepoReferenceFromUrl(Map<String, String> args, Map<String, String> templateArgs)
|
||||
{
|
||||
String store_type = templateArgs.get("store_type");
|
||||
String store_id = templateArgs.get("store_id");
|
||||
if (store_type != null && store_id != null)
|
||||
{
|
||||
return new StoreRepositoryReference(cmisService, store_type + ":" + store_id);
|
||||
}
|
||||
|
||||
String store = templateArgs.get("store");
|
||||
if (store != null)
|
||||
{
|
||||
return new StoreRepositoryReference(cmisService, store);
|
||||
}
|
||||
|
||||
// TODO: repository id
|
||||
// String repoId = templateArgs.get("repo");
|
||||
// else if (repoId != null)
|
||||
// {
|
||||
// }
|
||||
|
||||
return new DefaultRepositoryReference(cmisService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create CMIS Object Reference from URL segments
|
||||
*
|
||||
* @param args url arguments
|
||||
* @param templateArgs url template arguments
|
||||
* @return Repository Reference (or null, in case of bad url)
|
||||
*/
|
||||
public CMISObjectReference createObjectReferenceFromUrl(Map<String, String> args, Map<String, String> templateArgs)
|
||||
{
|
||||
// Despite the name of this argument, it is included in the "Object by ID" URL template and actually accepts a
|
||||
// value in object ID format (including version label suffix) so should be parsed as an object ID rather than a
|
||||
// NodeRef
|
||||
String objectId = args.get("noderef");
|
||||
if (objectId != null)
|
||||
{
|
||||
return new ObjectIdReference(cmisService, objectId);
|
||||
}
|
||||
|
||||
CMISRepositoryReference repo = createRepoReferenceFromUrl(args, templateArgs);
|
||||
String id = templateArgs.get("id");
|
||||
if (id != null)
|
||||
{
|
||||
return new NodeIdReference(cmisService, repo, id);
|
||||
}
|
||||
|
||||
String path = templateArgs.get("path");
|
||||
if (path == null)
|
||||
{
|
||||
path = args.get("path");
|
||||
}
|
||||
if (path != null)
|
||||
{
|
||||
return new ObjectPathReference(cmisService, repo, path);
|
||||
}
|
||||
|
||||
String avmPath = templateArgs.get("avmpath");
|
||||
if (avmPath != null)
|
||||
{
|
||||
return new AVMPathReference(cmisService, repo, avmPath);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create CMIS Relationship Reference from URL segments
|
||||
*
|
||||
* @param args url arguments
|
||||
* @param templateArgs url template arguments
|
||||
* @return Repository Reference (or null, in case of bad url)
|
||||
*/
|
||||
public CMISRelationshipReference createRelationshipReferenceFromUrl(Map<String, String> args, Map<String, String> templateArgs)
|
||||
{
|
||||
String assocId = templateArgs.get("assoc_id");
|
||||
if (assocId != null)
|
||||
{
|
||||
return new AssociationIdRelationshipReference(cmisService, assocId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISRelationshipReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
|
||||
/**
|
||||
* Source Node / Rel Type / Target Node Relationship Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class SourceTypeTargetRelationshipReference implements CMISRelationshipReference
|
||||
{
|
||||
protected CMISServices cmisServices;
|
||||
protected StoreRepositoryReference repo;
|
||||
protected CMISTypeDefinition type;
|
||||
protected NodeRef source;
|
||||
protected NodeRef target;
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param type
|
||||
* @param srcStore
|
||||
* @param srcId
|
||||
* @param tgtStore
|
||||
* @param tgtId
|
||||
*/
|
||||
public SourceTypeTargetRelationshipReference(CMISServices cmisServices, CMISTypeDefinition type, String srcStore, String srcId, String tgtStore, String tgtId)
|
||||
{
|
||||
this.cmisServices = cmisServices;
|
||||
this.repo = new StoreRepositoryReference(cmisServices, srcStore);
|
||||
this.type = type;
|
||||
this.source = new NodeRef(repo.getStoreRef(), srcId);
|
||||
StoreRepositoryReference tgtStoreRef = new StoreRepositoryReference(cmisServices, tgtStore);
|
||||
this.target = new NodeRef(tgtStoreRef.getStoreRef(), tgtId);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISRelationshipReference#getRepositoryReference()
|
||||
*/
|
||||
public CMISRepositoryReference getRepositoryReference()
|
||||
{
|
||||
return repo;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISRelationshipReference#getAssocRef()
|
||||
*/
|
||||
public AssociationRef getAssocRef()
|
||||
{
|
||||
return cmisServices.getRelationship(type, source, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "SourceTypeTargetRelationshipReference[type=" + type.getTypeId().getId() + ",source=" + source.toString() + ",target=" + target.toString() + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.reference;
|
||||
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
|
||||
/**
|
||||
* Store Ref Repository Reference
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class StoreRepositoryReference extends AbstractRepositoryReference
|
||||
{
|
||||
private StoreRef storeRef;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param storeRef
|
||||
*/
|
||||
public StoreRepositoryReference(CMISServices cmisServices, StoreRef storeRef)
|
||||
{
|
||||
super(cmisServices);
|
||||
this.storeRef = storeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param cmisServices
|
||||
* @param store accept storeType://storeId, storeType:storeId, storeId
|
||||
*/
|
||||
public StoreRepositoryReference(CMISServices cmisServices, String store)
|
||||
{
|
||||
super(cmisServices);
|
||||
|
||||
if (store.indexOf(StoreRef.URI_FILLER) != -1)
|
||||
{
|
||||
storeRef = new StoreRef(store);
|
||||
}
|
||||
else if (store.indexOf(':') != -1)
|
||||
{
|
||||
String[] storeParts = store.split(":");
|
||||
storeRef = new StoreRef(storeParts[0], storeParts[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, store);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.cmis.CMISRepositoryReference#getStoreRef()
|
||||
*/
|
||||
public StoreRef getStoreRef()
|
||||
{
|
||||
return storeRef;
|
||||
}
|
||||
|
||||
}
|
@@ -26,6 +26,7 @@ package org.alfresco.repo.cmis.rest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.cmis.CMISTypesFilterEnum;
|
||||
import org.alfresco.repo.template.TemplateNode;
|
||||
@@ -33,6 +34,7 @@ import org.alfresco.repo.web.scripts.RepositoryImageResolver;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
@@ -98,7 +100,15 @@ public class CMISChildrenMethod implements TemplateMethodModelEx
|
||||
}
|
||||
|
||||
// query children
|
||||
NodeRef[] childNodeRefs = cmisService.getChildren(nodeRef, typesFilter);
|
||||
NodeRef[] childNodeRefs;
|
||||
try
|
||||
{
|
||||
childNodeRefs = cmisService.getChildren(nodeRef, typesFilter, null);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
children = new TemplateNode[childNodeRefs.length];
|
||||
for (int i = 0; i < childNodeRefs.length; i++)
|
||||
{
|
||||
|
@@ -26,9 +26,11 @@ package org.alfresco.repo.cmis.rest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.repo.template.TemplateAssociation;
|
||||
import org.alfresco.repo.template.TemplateNode;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.ext.beans.BeansWrapper;
|
||||
@@ -90,7 +92,14 @@ public final class CMISPropertyValueMethod implements TemplateMethodModelEx
|
||||
if (wrapped != null && wrapped instanceof TemplateNode)
|
||||
{
|
||||
// retrieve property value from node
|
||||
result = cmisService.getProperty(((TemplateNode)wrapped).getNodeRef(), propertyName);
|
||||
try
|
||||
{
|
||||
result = cmisService.getProperty(((TemplateNode)wrapped).getNodeRef(), propertyName);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
else if (wrapped != null && wrapped instanceof TemplateAssociation)
|
||||
{
|
||||
|
@@ -27,12 +27,14 @@ package org.alfresco.repo.cmis.rest;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.CMISFilterNotValidException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.repo.template.TemplateNode;
|
||||
import org.alfresco.repo.web.scripts.RepositoryImageResolver;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.service.cmr.repository.TemplateValueConverter;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
import freemarker.ext.beans.BeanModel;
|
||||
import freemarker.template.TemplateMethodModelEx;
|
||||
@@ -102,7 +104,15 @@ public class CMISRenditionsMethod implements TemplateMethodModelEx
|
||||
// query renditions
|
||||
if (nodeRef != null)
|
||||
{
|
||||
Map<String, Object> renditions = cmisService.getRenditions(nodeRef, renditionFilter);
|
||||
Map<String, Object> renditions;
|
||||
try
|
||||
{
|
||||
renditions = cmisService.getRenditions(nodeRef, renditionFilter);
|
||||
}
|
||||
catch (CMISFilterNotValidException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
return templateValueConverter.convertValue(renditions, imageResolver);
|
||||
}
|
||||
|
||||
|
@@ -41,7 +41,10 @@ import org.alfresco.cmis.CMISCapabilityChanges;
|
||||
import org.alfresco.cmis.CMISChangeEvent;
|
||||
import org.alfresco.cmis.CMISChangeLog;
|
||||
import org.alfresco.cmis.CMISChangeLogService;
|
||||
import org.alfresco.cmis.CMISConstraintException;
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISJoinEnum;
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.CMISPermissionDefinition;
|
||||
@@ -54,14 +57,15 @@ import org.alfresco.cmis.CMISRelationshipDirectionEnum;
|
||||
import org.alfresco.cmis.CMISRelationshipReference;
|
||||
import org.alfresco.cmis.CMISRepositoryReference;
|
||||
import org.alfresco.cmis.CMISResultSet;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.cmis.CMISTypesFilterEnum;
|
||||
import org.alfresco.cmis.CMISVersioningStateEnum;
|
||||
import org.alfresco.cmis.CMISQueryOptions.CMISQueryMode;
|
||||
import org.alfresco.cmis.acl.CMISAccessControlEntryImpl;
|
||||
import org.alfresco.cmis.reference.NodeRefReference;
|
||||
import org.alfresco.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.cmis.reference.ObjectIdReference;
|
||||
import org.alfresco.repo.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.repo.jscript.Association;
|
||||
import org.alfresco.repo.jscript.BaseScopableProcessorExtension;
|
||||
import org.alfresco.repo.jscript.ScriptNode;
|
||||
@@ -73,16 +77,18 @@ import org.alfresco.repo.web.util.paging.Paging;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.mozilla.javascript.Context;
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
import org.mozilla.javascript.ScriptableObject;
|
||||
import org.springframework.extensions.webscripts.Status;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
|
||||
|
||||
/**
|
||||
* CMIS Javascript API
|
||||
* CMIS Javascript API.
|
||||
*
|
||||
* @author davic
|
||||
* @author davidc
|
||||
* @author dward
|
||||
*/
|
||||
public class CMISScript extends BaseScopableProcessorExtension
|
||||
{
|
||||
@@ -117,12 +123,13 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
public static final String ARG_THIS_VERSION = "thisVersion";
|
||||
public static final String ARG_TYPE_ID = "typeId";
|
||||
public static final String ARG_TYPES = "types";
|
||||
public static final String ARG_UNFILE_MULTIFILE_DOCUMENTS = "unfileMultiFiledDocuments";
|
||||
public static final String ARG_UNFILE_OBJECTS = "unfileObjects";
|
||||
public static final String ARG_VERSIONING_STATE = "versioningState";
|
||||
public static final String ARG_SOURCE_FOLDER_ID = "sourceFolderId";
|
||||
public static final String ARG_INCLUDE_ACL = "includeACL";
|
||||
public static final String ARG_RENDITION_FILTER = "renditionFilter";
|
||||
public static final String ARG_CHANGE_LOG_TOKEN = "changeLogToken";
|
||||
public static final String ARG_ORDER_BY = "orderBy";
|
||||
|
||||
// service dependencies
|
||||
private ServiceRegistry services;
|
||||
@@ -147,9 +154,10 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the paging helper
|
||||
* Set the paging helper.
|
||||
*
|
||||
* @param paging
|
||||
* the paging helper
|
||||
*/
|
||||
public void setPaging(Paging paging)
|
||||
{
|
||||
@@ -157,9 +165,10 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CMIS Service
|
||||
* Set the CMIS Service.
|
||||
*
|
||||
* @param cmisService
|
||||
* the cmis service
|
||||
*/
|
||||
public void setCMISService(CMISServices cmisService)
|
||||
{
|
||||
@@ -167,9 +176,10 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CMIS Dictionary Service
|
||||
* Set the CMIS Dictionary Service.
|
||||
*
|
||||
* @param cmisDictionaryService
|
||||
* the cmis dictionary service
|
||||
*/
|
||||
public void setCMISDictionaryService(CMISDictionaryService cmisDictionaryService)
|
||||
{
|
||||
@@ -177,9 +187,10 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CMIS Query Service
|
||||
* Set the CMIS Query Service.
|
||||
*
|
||||
* @param cmisQueryService
|
||||
* the cmis query service
|
||||
*/
|
||||
public void setCMISQueryService(CMISQueryService cmisQueryService)
|
||||
{
|
||||
@@ -208,9 +219,10 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CMIS Reference Factory
|
||||
*
|
||||
* Set the CMIS Reference Factory.
|
||||
*
|
||||
* @param referenceFactory
|
||||
* the reference factory
|
||||
*/
|
||||
public void setCMISReferenceFactory(ReferenceFactory referenceFactory)
|
||||
{
|
||||
@@ -337,7 +349,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
*/
|
||||
public CMISObjectReference createObjectIdReference(String objectId)
|
||||
{
|
||||
return new NodeRefReference(cmisService, objectId);
|
||||
return new ObjectIdReference(cmisService, objectId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -375,15 +387,29 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
/**
|
||||
* Query for node children
|
||||
*
|
||||
* @param parent node to query children for
|
||||
* @param typesFilter types filter
|
||||
* @param page page to query for
|
||||
* @return paged result set of children
|
||||
* @param parent
|
||||
* node to query children for
|
||||
* @param typesFilter
|
||||
* types filter
|
||||
* @param orderBy
|
||||
* comma-separated list of query names and the ascending modifier "ASC" or the descending modifier "DESC"
|
||||
* for each query name
|
||||
* @param page
|
||||
* page to query for
|
||||
* @return paged result set of children
|
||||
*/
|
||||
public PagedResults queryChildren(ScriptNode parent, String typesFilter, Page page)
|
||||
public PagedResults queryChildren(ScriptNode parent, String typesFilter, String orderBy, Page page)
|
||||
{
|
||||
CMISTypesFilterEnum filter = resolveTypesFilter(typesFilter);
|
||||
NodeRef[] children = cmisService.getChildren(parent.getNodeRef(), filter);
|
||||
NodeRef[] children;
|
||||
try
|
||||
{
|
||||
children = cmisService.getChildren(parent.getNodeRef(), filter, orderBy);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
|
||||
Cursor cursor = paging.createCursor(children.length, page);
|
||||
ScriptNode[] nodes = new ScriptNode[cursor.getRowCount()];
|
||||
@@ -408,7 +434,15 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
*/
|
||||
public PagedResults queryRelationships(ScriptNode node, CMISTypeDefinition relDef, boolean includeSubTypes, CMISRelationshipDirectionEnum direction, Page page)
|
||||
{
|
||||
AssociationRef[] relationships = cmisService.getRelationships(node.getNodeRef(), relDef, includeSubTypes, direction);
|
||||
AssociationRef[] relationships;
|
||||
try
|
||||
{
|
||||
relationships = cmisService.getRelationships(node.getNodeRef(), relDef, includeSubTypes, direction);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
|
||||
Cursor cursor = paging.createCursor(relationships.length, page);
|
||||
Association[] assocs = new Association[cursor.getRowCount()];
|
||||
@@ -421,31 +455,6 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for items checked-out to user
|
||||
*
|
||||
* @param username user
|
||||
* @param page
|
||||
* @return paged result set of checked-out items
|
||||
*/
|
||||
public PagedResults queryCheckedOut(String username, Page page)
|
||||
{
|
||||
return queryCheckedOut(username, null, false, page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for items checked-out to user within folder
|
||||
*
|
||||
* @param username user
|
||||
* @param folder folder
|
||||
* @param page
|
||||
* @return paged result set of checked-out items
|
||||
*/
|
||||
public PagedResults queryCheckedOut(String username, ScriptNode folder, Page page)
|
||||
{
|
||||
return queryCheckedOut(username, folder, false, page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for items checked-out to user within folder (and possibly descendants)
|
||||
*
|
||||
@@ -457,7 +466,15 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
*/
|
||||
public PagedResults queryCheckedOut(String username, ScriptNode folder, boolean includeDescendants, Page page)
|
||||
{
|
||||
NodeRef[] checkedout = cmisService.getCheckedOut(username, (folder == null) ? null : folder.getNodeRef(), includeDescendants);
|
||||
NodeRef[] checkedout;
|
||||
try
|
||||
{
|
||||
checkedout = cmisService.getCheckedOut(username, (folder == null) ? null : folder.getNodeRef(), includeDescendants, null);
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
Cursor cursor = paging.createCursor(checkedout.length, page);
|
||||
ScriptNode[] nodes = new ScriptNode[cursor.getRowCount()];
|
||||
for (int i = cursor.getStartRow(); i <= cursor.getEndRow(); i++)
|
||||
@@ -470,15 +487,18 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for child types (of a given type), or the base types (if no type given)
|
||||
* Query for child types (of a given type), or the base types (if no type given).
|
||||
*
|
||||
* @param typeDef
|
||||
* the type def
|
||||
* @param page
|
||||
* @return
|
||||
* the page
|
||||
* @return the paged results
|
||||
*/
|
||||
public PagedResults queryTypeChildren(CMISTypeDefinition typeDef, Page page)
|
||||
{
|
||||
Collection<CMISTypeDefinition> children = (typeDef == null) ? cmisDictionaryService.getBaseTypes() : typeDef.getSubTypes(false);
|
||||
Collection<CMISTypeDefinition> children = (typeDef == null) ? cmisService.getBaseTypes() : typeDef
|
||||
.getSubTypes(false);
|
||||
Cursor cursor = paging.createCursor(children.size(), page);
|
||||
|
||||
// skip
|
||||
@@ -500,47 +520,49 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for a Type Definition given a CMIS Type Id
|
||||
* Query for a Type Definition given a CMIS Type Id.
|
||||
*
|
||||
* @param page
|
||||
* @return CMIS Type Definition
|
||||
* @param typeId
|
||||
* the type id
|
||||
* @return CMIS Type Definition
|
||||
*/
|
||||
public CMISTypeDefinition queryType(String typeId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return cmisDictionaryService.findType(typeId);
|
||||
return cmisService.getTypeDefinition(typeId);
|
||||
}
|
||||
catch(AlfrescoRuntimeException e)
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
return null;
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the Type Definition for the given Node
|
||||
* Query the Type Definition for the given Node.
|
||||
*
|
||||
* @param node
|
||||
* @return CMIS Type Definition
|
||||
* the node
|
||||
* @return CMIS Type Definition
|
||||
*/
|
||||
public CMISTypeDefinition queryType(ScriptNode node)
|
||||
{
|
||||
try
|
||||
{
|
||||
QName typeQName = node.getQNameType();
|
||||
return cmisDictionaryService.findTypeForClass(typeQName);
|
||||
return cmisService.getTypeDefinition(node.getNodeRef());
|
||||
}
|
||||
catch(AlfrescoRuntimeException e)
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
return null;
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the Property Definition for the given Property
|
||||
* Query the Property Definition for the given Property.
|
||||
*
|
||||
* @param propertyName
|
||||
* @return
|
||||
* the property name
|
||||
* @return the CMIS property definition
|
||||
*/
|
||||
public CMISPropertyDefinition queryProperty(String propertyName)
|
||||
{
|
||||
@@ -553,8 +575,8 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
|
||||
/**
|
||||
* Can you query the private working copy of a document.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @return is the PWC searchable?
|
||||
*/
|
||||
public boolean getPwcSearchable()
|
||||
{
|
||||
@@ -576,7 +598,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
/**
|
||||
* Get the query support level.
|
||||
*
|
||||
* @return
|
||||
* @return the query support level
|
||||
*/
|
||||
public CMISQueryEnum getQuerySupport()
|
||||
{
|
||||
@@ -586,7 +608,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
/**
|
||||
* Get the join support level in queries.
|
||||
*
|
||||
* @return
|
||||
* @return the join support level
|
||||
*/
|
||||
public CMISJoinEnum getJoinSupport()
|
||||
{
|
||||
@@ -594,12 +616,13 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue query
|
||||
* Issue query.
|
||||
*
|
||||
* @param statement query statement
|
||||
* @param statement
|
||||
* query statement
|
||||
* @param page
|
||||
*
|
||||
* @return paged result set
|
||||
* the page
|
||||
* @return paged result set
|
||||
*/
|
||||
public PagedResults query(String statement, Page page)
|
||||
{
|
||||
@@ -624,7 +647,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the supported permission types
|
||||
* Gets the supported permission types.
|
||||
*
|
||||
* @return the supported permission types
|
||||
*/
|
||||
@@ -645,6 +668,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
|
||||
/**
|
||||
* Get all the permissions defined by the repository.
|
||||
*
|
||||
* @return a list of permissions
|
||||
*/
|
||||
public List<CMISPermissionDefinition> getRepositoryPermissions()
|
||||
@@ -655,6 +679,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
|
||||
/**
|
||||
* Get the list of permission mappings.
|
||||
*
|
||||
* @return get the permission mapping as defined by the CMIS specification.
|
||||
*/
|
||||
public List<? extends CMISPermissionMapping> getPermissionMappings()
|
||||
@@ -684,6 +709,16 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
return cmisAccessControlService.getPrincipalAnyone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies an ACL to a node.
|
||||
*
|
||||
* @param node
|
||||
* the node
|
||||
* @param principalIds
|
||||
* the principal IDs
|
||||
* @param permissions
|
||||
* the permissions for each principal ID
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void applyACL(ScriptNode node, Serializable principalIds, Serializable permissions)
|
||||
{
|
||||
@@ -694,7 +729,15 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
{
|
||||
acesToApply.add(new CMISAccessControlEntryImpl(principalList.get(i), permissionList.get(i)));
|
||||
}
|
||||
cmisAccessControlService.applyAcl(node.getNodeRef(), acesToApply);
|
||||
try
|
||||
{
|
||||
cmisAccessControlService.applyAcl(node.getNodeRef(), acesToApply);
|
||||
}
|
||||
catch (CMISConstraintException e)
|
||||
{
|
||||
// Force the appropriate status code on error
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -779,7 +822,7 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
Scriptable changeNodes = cx.newArray(scope, size);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
ScriptableObject.putProperty(changeNodes, i, new ScriptNode(changeEvents.get(i).getNode(), services,
|
||||
ScriptableObject.putProperty(changeNodes, i, new ScriptNode(changeEvents.get(i).getChangedNode(), services,
|
||||
scope));
|
||||
}
|
||||
ScriptableObject.putProperty(changeLogMap, "changeNodes", changeNodes);
|
||||
@@ -811,9 +854,298 @@ public class CMISScript extends BaseScopableProcessorExtension
|
||||
}
|
||||
return changeLogMap;
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a versioning state to a new node, potentially resulting in a new node.
|
||||
*
|
||||
* @param source
|
||||
* the source
|
||||
* @param versioningState
|
||||
* the versioning state
|
||||
* @return the node to write changes to
|
||||
* @throws CMISConstraintException
|
||||
*/
|
||||
public ScriptNode applyVersioningState(ScriptNode source, String versioningState)
|
||||
{
|
||||
CMISVersioningStateEnum versioningStateEnum = CMISVersioningStateEnum.FACTORY.fromLabel(versioningState);
|
||||
try
|
||||
{
|
||||
return new ScriptNode(cmisService.applyVersioningState(source.getNodeRef(), versioningStateEnum), services,
|
||||
getScope());
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks out an object by ID.
|
||||
*
|
||||
* @param objectId
|
||||
* the object id
|
||||
* @return the private working copy node
|
||||
*/
|
||||
public ScriptNode checkOut(String objectId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ScriptNode(cmisService.checkOut(objectId), services, getScope());
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks in a given private working copy node.
|
||||
*
|
||||
* @param source
|
||||
* the node
|
||||
* @param checkinComment
|
||||
* the checkin comment
|
||||
* @param isMajor
|
||||
* is this a major version?
|
||||
* @return the checked-in node
|
||||
*/
|
||||
public ScriptNode checkIn(ScriptNode source, String checkinComment, boolean isMajor)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ScriptNode(cmisService.checkIn((String) cmisService.getProperty(source.getNodeRef(), CMISDictionaryModel.PROP_OBJECT_ID), checkinComment, isMajor), services,
|
||||
getScope());
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels a check out.
|
||||
*
|
||||
* @param source
|
||||
* the private working copy
|
||||
*/
|
||||
public void cancelCheckOut(ScriptNode source)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.cancelCheckOut((String) cmisService.getProperty(source.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID));
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the versions of a node.
|
||||
*
|
||||
* @param source
|
||||
* the node
|
||||
* @return a Javascript array of all the versions
|
||||
*/
|
||||
public Scriptable getAllVersions(ScriptNode source)
|
||||
{
|
||||
Scriptable scope = getScope();
|
||||
Context cx = Context.enter();
|
||||
try
|
||||
{
|
||||
List<NodeRef> allVersions = cmisService.getAllVersions((String) cmisService.getProperty(
|
||||
source.getNodeRef(), CMISDictionaryModel.PROP_OBJECT_ID));
|
||||
// Wrap the version
|
||||
int size = allVersions.size();
|
||||
Scriptable allVersionsArr = cx.newArray(scope, size);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
ScriptableObject.putProperty(allVersionsArr, i, new ScriptNode(allVersions.get(i), services, scope));
|
||||
}
|
||||
return allVersionsArr;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the required version of a node
|
||||
*
|
||||
* @param source
|
||||
* the node
|
||||
* @param returnVersion
|
||||
* value indicating version required
|
||||
* @return the version
|
||||
*/
|
||||
public ScriptNode getReturnVersion(ScriptNode source, String returnVersion)
|
||||
{
|
||||
if (returnVersion == null || returnVersion.equals("this"))
|
||||
{
|
||||
return source;
|
||||
}
|
||||
try
|
||||
{
|
||||
return new ScriptNode(cmisService.getLatestVersion((String) cmisService.getProperty(source.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), returnVersion.equals("latestmajor")), services, getScope());
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to delete a folder and all of its children, recording the status in the given status object.
|
||||
*
|
||||
* @param source
|
||||
* the folder node
|
||||
* @param status
|
||||
* the status
|
||||
* @param continueOnFailure
|
||||
* should we continue if an error occurs with one of the children?
|
||||
* @param unfile
|
||||
* should we remove non-primary associations to nodes rather than delete them?
|
||||
* @param deleteAllVersions
|
||||
* should we delete all the versions of the nodes we delete?
|
||||
*/
|
||||
public void deleteTree(ScriptNode source, Status status, boolean continueOnFailure, boolean unfile,
|
||||
boolean deleteAllVersions)
|
||||
{
|
||||
// Let's avoid all deletions getting rolled back by catching the exception and setting the status ourselves
|
||||
try
|
||||
{
|
||||
cmisService.deleteTreeReportLastError((String) cmisService.getProperty(source.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), continueOnFailure, unfile, deleteAllVersions);
|
||||
// Success, but no response content
|
||||
status.setCode(Status.STATUS_NO_CONTENT);
|
||||
status.setRedirect(true);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
status.setCode(e.getStatusCode());
|
||||
status.setMessage(e.getMessage());
|
||||
status.setRedirect(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a node's content stream.
|
||||
*
|
||||
* @param source
|
||||
* the node
|
||||
*/
|
||||
public void deleteContentStream(ScriptNode source)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.deleteContentStream((String) cmisService.getProperty(source.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID));
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a node.
|
||||
*
|
||||
* @param source
|
||||
* the node
|
||||
* @param allVersions
|
||||
* should we delete all the versions of the node?
|
||||
*/
|
||||
public void deleteObject(ScriptNode source, boolean allVersions)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.deleteObject((String) cmisService.getProperty(source.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), allVersions);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an association.
|
||||
*
|
||||
* @param assoc
|
||||
* the association
|
||||
*/
|
||||
public void deleteObject(Association assoc)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.deleteObject((String) cmisService.getProperty(assoc.getAssociationRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), true);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an object to a folder.
|
||||
*
|
||||
* @param child
|
||||
* the object to add
|
||||
* @param parent
|
||||
* the folder
|
||||
*/
|
||||
public void addObjectToFolder(ScriptNode child, ScriptNode parent)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.addObjectToFolder((String) cmisService.getProperty(child.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), (String) cmisService.getProperty(parent.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID));
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves an object from a source folder to a target folder.
|
||||
*
|
||||
* @param child
|
||||
* the object to move
|
||||
* @param targetFolder
|
||||
* the target folder
|
||||
* @param sourceFolderId
|
||||
* the source folder object ID
|
||||
*/
|
||||
public void moveObject(ScriptNode child, ScriptNode targetFolder, String sourceFolderId)
|
||||
{
|
||||
try
|
||||
{
|
||||
cmisService.moveObject((String) cmisService.getProperty(child.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), (String) cmisService.getProperty(targetFolder.getNodeRef(),
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), sourceFolderId);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -31,6 +31,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.CMISPropertyDefinition;
|
||||
import org.alfresco.cmis.CMISResultSet;
|
||||
import org.alfresco.cmis.CMISResultSetColumn;
|
||||
import org.alfresco.cmis.CMISResultSetMetaData;
|
||||
@@ -233,6 +234,18 @@ public class CMISTemplateResultSet implements Serializable
|
||||
CMISResultSetColumn col = resultSet.getMetaData().getColumn(colName);
|
||||
return col == null ? null : col.getCMISDataType().getLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets property definition for specified column name
|
||||
*
|
||||
* @param colName column name
|
||||
* @return property definition (or null, if not applicable)
|
||||
*/
|
||||
public CMISPropertyDefinition getPropertyDefinition(String colName)
|
||||
{
|
||||
CMISResultSetColumn col = resultSet.getMetaData().getColumn(colName);
|
||||
return col == null ? null : col.getCMISPropertyDefinition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets node for specified selector
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -15,60 +15,61 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
import org.alfresco.cmis.CMISAccessControlEntry;
|
||||
import org.alfresco.cmis.CMISAccessControlFormatEnum;
|
||||
import org.alfresco.cmis.CMISAccessControlReport;
|
||||
import org.alfresco.cmis.CMISAccessControlService;
|
||||
import org.alfresco.cmis.CMISAclPropagationEnum;
|
||||
import org.alfresco.cmis.CMISActionEvaluator;
|
||||
import org.alfresco.cmis.CMISAllowedActionEnum;
|
||||
import org.alfresco.cmis.CMISChangeLogService;
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISConstraintException;
|
||||
import org.alfresco.cmis.CMISFilterNotValidException;
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISQueryService;
|
||||
import org.alfresco.cmis.CMISRendition;
|
||||
import org.alfresco.cmis.CMISRenditionService;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.cmis.acl.CMISAccessControlEntryImpl;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.cmis.ws.utils.PropertyUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.repo.web.util.paging.Page;
|
||||
import org.alfresco.repo.web.util.paging.Paging;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
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.search.SearchService;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.service.descriptor.DescriptorService;
|
||||
|
||||
/**
|
||||
@@ -81,24 +82,41 @@ import org.alfresco.service.descriptor.DescriptorService;
|
||||
*/
|
||||
public class DMAbstractServicePort
|
||||
{
|
||||
protected static final String INITIAL_VERSION_DESCRIPTION = "Initial version";
|
||||
private static final String CMIS_USER = "cmis:user";
|
||||
|
||||
private static final String INVALID_REPOSITORY_ID_MESSAGE = "Invalid repository id";
|
||||
private static final String INVALID_FOLDER_OBJECT_ID_MESSAGE = "OID for non-existent object or not folder object";
|
||||
|
||||
private static final Map<EnumACLPropagation, CMISAclPropagationEnum> ACL_PROPAGATION_ENUM_MAPPGIN;
|
||||
private static final Map<CMISAllowedActionEnum, PropertyDescriptor> ALLOWED_ACTION_ENUM_MAPPING;
|
||||
static
|
||||
{
|
||||
ACL_PROPAGATION_ENUM_MAPPGIN = new HashMap<EnumACLPropagation, CMISAclPropagationEnum>();
|
||||
ACL_PROPAGATION_ENUM_MAPPGIN.put(EnumACLPropagation.OBJECTONLY, CMISAclPropagationEnum.OBJECT_ONLY);
|
||||
ACL_PROPAGATION_ENUM_MAPPGIN.put(EnumACLPropagation.PROPAGATE, CMISAclPropagationEnum.PROPAGATE);
|
||||
ACL_PROPAGATION_ENUM_MAPPGIN.put(EnumACLPropagation.REPOSITORYDETERMINED, CMISAclPropagationEnum.REPOSITORY_DETERMINED);
|
||||
|
||||
try
|
||||
{
|
||||
ALLOWED_ACTION_ENUM_MAPPING = new HashMap<CMISAllowedActionEnum, PropertyDescriptor>(97);
|
||||
for (PropertyDescriptor propertyDescriptor : Introspector.getBeanInfo(CmisAllowableActionsType.class, Object.class).getPropertyDescriptors())
|
||||
{
|
||||
String label = propertyDescriptor.getName();
|
||||
CMISAllowedActionEnum allowedActionEnum = CMISAllowedActionEnum.FACTORY.fromLabel(label);
|
||||
if (allowedActionEnum != null)
|
||||
{
|
||||
ALLOWED_ACTION_ENUM_MAPPING.put(allowedActionEnum, propertyDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IntrospectionException e)
|
||||
{
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Paging paging = new Paging();
|
||||
|
||||
protected ObjectFactory cmisObjectFactory = new ObjectFactory();
|
||||
protected CMISDictionaryService cmisDictionaryService;
|
||||
protected CMISQueryService cmisQueryService;
|
||||
protected CMISServices cmisService;
|
||||
protected CMISChangeLogService cmisChangeLogService;
|
||||
@@ -107,11 +125,8 @@ public class DMAbstractServicePort
|
||||
|
||||
protected DescriptorService descriptorService;
|
||||
protected NodeService nodeService;
|
||||
protected VersionService versionService;
|
||||
protected FileFolderService fileFolderService;
|
||||
protected CheckOutCheckInService checkOutCheckInService;
|
||||
protected SearchService searchService;
|
||||
protected CmisObjectsUtils cmisObjectsUtils;
|
||||
protected PropertyUtil propertiesUtil;
|
||||
protected PermissionService permissionService;
|
||||
|
||||
@@ -120,11 +135,6 @@ public class DMAbstractServicePort
|
||||
this.cmisService = cmisService;
|
||||
}
|
||||
|
||||
public void setCmisDictionaryService(CMISDictionaryService cmisDictionaryService)
|
||||
{
|
||||
this.cmisDictionaryService = cmisDictionaryService;
|
||||
}
|
||||
|
||||
public void setCmisQueryService(CMISQueryService cmisQueryService)
|
||||
{
|
||||
this.cmisQueryService = cmisQueryService;
|
||||
@@ -155,27 +165,11 @@ public class DMAbstractServicePort
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setVersionService(VersionService versionService)
|
||||
{
|
||||
this.versionService = versionService;
|
||||
}
|
||||
|
||||
public void setFileFolderService(FileFolderService fileFolderService)
|
||||
{
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
public void setCheckOutCheckInService(CheckOutCheckInService checkOutCheckInService)
|
||||
{
|
||||
|
||||
this.checkOutCheckInService = checkOutCheckInService;
|
||||
}
|
||||
|
||||
public void setCmisObjectsUtils(CmisObjectsUtils cmisObjectsUtils)
|
||||
{
|
||||
this.cmisObjectsUtils = cmisObjectsUtils;
|
||||
}
|
||||
|
||||
public void setPropertiesUtil(PropertyUtil propertiesUtil)
|
||||
{
|
||||
this.propertiesUtil = propertiesUtil;
|
||||
@@ -193,7 +187,7 @@ public class DMAbstractServicePort
|
||||
|
||||
protected PropertyFilter createPropertyFilter(String filter) throws CmisException
|
||||
{
|
||||
return (filter == null) ? (new PropertyFilter()) : (new PropertyFilter(filter, cmisObjectsUtils));
|
||||
return (filter == null) ? (new PropertyFilter()) : (new PropertyFilter(filter));
|
||||
}
|
||||
|
||||
protected PropertyFilter createPropertyFilter(JAXBElement<String> element) throws CmisException
|
||||
@@ -239,7 +233,7 @@ public class DMAbstractServicePort
|
||||
protected CmisObjectType createCmisObject(Object identifier, PropertyFilter filter, boolean includeAllowableActions, String renditionFilter) throws CmisException
|
||||
{
|
||||
CmisObjectType result = new CmisObjectType();
|
||||
result.setProperties(propertiesUtil.getPropertiesType(identifier.toString(), filter));
|
||||
result.setProperties(propertiesUtil.getProperties(identifier, filter));
|
||||
if (includeAllowableActions)
|
||||
{
|
||||
result.setAllowableActions(determineObjectAllowableActions(identifier));
|
||||
@@ -255,20 +249,6 @@ public class DMAbstractServicePort
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts "Folder with folderNodeRef exists"
|
||||
*
|
||||
* @param folderNodeRef node reference
|
||||
* @throws FolderNotValidException folderNodeRef doesn't exist or folderNodeRef isn't for folder object
|
||||
*/
|
||||
protected void assertExistFolder(NodeRef folderNodeRef) throws CmisException
|
||||
{
|
||||
if (!this.cmisObjectsUtils.isFolder(folderNodeRef))
|
||||
{
|
||||
throw new CmisException(INVALID_FOLDER_OBJECT_ID_MESSAGE, cmisObjectsUtils.createCmisException(INVALID_FOLDER_OBJECT_ID_MESSAGE, EnumServiceException.INVALID_ARGUMENT));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks specified in CMIS request parameters repository Id.
|
||||
*
|
||||
@@ -279,54 +259,29 @@ public class DMAbstractServicePort
|
||||
{
|
||||
if (!this.descriptorService.getCurrentRepositoryDescriptor().getId().equals(repositoryId))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(INVALID_REPOSITORY_ID_MESSAGE, EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException(INVALID_REPOSITORY_ID_MESSAGE, EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, Serializable> createVersionProperties(String versionDescription, VersionType versionType)
|
||||
{
|
||||
Map<String, Serializable> result = new HashMap<String, Serializable>();
|
||||
result.put(Version.PROP_DESCRIPTION, versionDescription);
|
||||
result.put(VersionModel.PROP_VERSION_TYPE, versionType);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected NodeRef checkoutNode(NodeRef documentNodeReference)
|
||||
{
|
||||
if (!this.nodeService.hasAspect(documentNodeReference, ContentModel.ASPECT_VERSIONABLE))
|
||||
{
|
||||
this.versionService.createVersion(documentNodeReference, createVersionProperties(INITIAL_VERSION_DESCRIPTION, VersionType.MAJOR));
|
||||
}
|
||||
return checkOutCheckInService.checkout(documentNodeReference);
|
||||
}
|
||||
|
||||
protected CMISTypeDefinition getCmisTypeDefinition(String typeId) throws CmisException
|
||||
{
|
||||
try
|
||||
{
|
||||
return cmisDictionaryService.findType(typeId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new CmisException(("Invalid typeId " + typeId), cmisObjectsUtils.createCmisException(("Invalid typeId " + typeId), EnumServiceException.INVALID_ARGUMENT));
|
||||
}
|
||||
}
|
||||
|
||||
protected List<CmisRenditionType> getRenditions(Object objectId, String renditionFilter) throws CmisException
|
||||
protected List<CmisRenditionType> getRenditions(Object object, String renditionFilter) throws CmisException
|
||||
{
|
||||
List<CmisRenditionType> result = null;
|
||||
if (NodeRef.isNodeRef(objectId.toString()))
|
||||
if (object instanceof Version)
|
||||
{
|
||||
NodeRef document = new NodeRef(objectId.toString());
|
||||
object = ((Version) object).getFrozenStateNodeRef();
|
||||
}
|
||||
if (object instanceof NodeRef)
|
||||
{
|
||||
NodeRef document = (NodeRef) object;
|
||||
|
||||
List<CMISRendition> renditions = null;
|
||||
try
|
||||
{
|
||||
renditions = cmisRenditionService.getRenditions(document, renditionFilter);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISFilterNotValidException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Invalid rendition filter", EnumServiceException.FILTER_NOT_VALID);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
if (renditions != null && !renditions.isEmpty())
|
||||
{
|
||||
@@ -372,130 +327,44 @@ public class DMAbstractServicePort
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String typeId = propertiesUtil.getProperty(object, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, null);
|
||||
CMISTypeDefinition objectType = (null == typeId) ? (null) : (cmisDictionaryService.findType(typeId));
|
||||
if (null == objectType)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Type Definition for specified Object was not found", EnumServiceException.STORAGE);
|
||||
}
|
||||
if (!objectType.isControllableACL())
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Object that was specified is not ACL Controllable", EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
CMISAclPropagationEnum propagation = (null == aclPropagation) ? (CMISAclPropagationEnum.PROPAGATE) : (ACL_PROPAGATION_ENUM_MAPPGIN.get(aclPropagation));
|
||||
List<CMISAccessControlEntry> acesToAdd = (null == addACEs) ? (null) : (convertToAlfrescoAceEntriesList(addACEs.getPermission()));
|
||||
List<CMISAccessControlEntry> acesToRemove = (null == removeACEs) ? (null) : (convertToAlfrescoAceEntriesList(removeACEs.getPermission()));
|
||||
CMISAccessControlReport aclReport = null;
|
||||
try
|
||||
{
|
||||
CMISAclPropagationEnum propagation = (null == aclPropagation) ? (CMISAclPropagationEnum.PROPAGATE) : (ACL_PROPAGATION_ENUM_MAPPGIN.get(aclPropagation));
|
||||
List<CMISAccessControlEntry> acesToAdd = (null == addACEs) ? (null) : (convertToAlfrescoAceEntriesList(addACEs.getPermission()));
|
||||
List<CMISAccessControlEntry> acesToRemove = (null == removeACEs) ? (null) : (convertToAlfrescoAceEntriesList(removeACEs.getPermission()));
|
||||
CMISAccessControlReport aclReport = null;
|
||||
aclReport = cmisAclService.applyAcl(object, acesToRemove, acesToAdd, propagation, CMISAccessControlFormatEnum.REPOSITORY_SPECIFIC_PERMISSIONS);
|
||||
CmisACLType result = convertAclReportToCmisAclType(aclReport);
|
||||
return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISConstraintException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Can't perform updating of Object Permissions. Error cause message: " + e.toString()), EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
CmisACLType result = convertAclReportToCmisAclType(aclReport);
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<CMISAccessControlEntry> convertToAlfrescoAceEntriesList(List<CmisAccessControlEntryType> source)
|
||||
private List<CMISAccessControlEntry> convertToAlfrescoAceEntriesList(List<CmisAccessControlEntryType> source) throws CmisException
|
||||
{
|
||||
List<CMISAccessControlEntry> result = new LinkedList<CMISAccessControlEntry>();
|
||||
for (CmisAccessControlEntryType cmisEntry : source)
|
||||
{
|
||||
result.add(convertToAlfrescoAceEntry(cmisEntry));
|
||||
if (!cmisEntry.isDirect())
|
||||
{
|
||||
throw ExceptionUtil.createCmisException("Inherited Permissions can't be updated or deleted from Object", EnumServiceException.NOT_SUPPORTED);
|
||||
}
|
||||
String principalId = cmisEntry.getPrincipal().getPrincipalId();
|
||||
if (CMIS_USER.equals(principalId))
|
||||
{
|
||||
principalId = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
}
|
||||
for (String permission : cmisEntry.getPermission())
|
||||
{
|
||||
result.add(new CMISAccessControlEntryImpl(principalId, permission));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private CMISAccessControlEntry convertToAlfrescoAceEntry(final CmisAccessControlEntryType entry)
|
||||
{
|
||||
final Holder<String> correctPrincipalId = new Holder<String>(entry.getPrincipal().getPrincipalId());
|
||||
if ("cmis:user".equals(correctPrincipalId))
|
||||
{
|
||||
correctPrincipalId.value = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
}
|
||||
CMISAccessControlEntry result = new CMISAccessControlEntry() // FIXME: It is better to use already implemented class of this interface
|
||||
{
|
||||
private String principalId;
|
||||
private String permission; // FIXME: [BUG] It MUST BE a List of permissions!!!
|
||||
private boolean direct;
|
||||
{
|
||||
|
||||
principalId = correctPrincipalId.value;
|
||||
permission = entry.getPermission().iterator().next(); // FIXME: See line 66
|
||||
direct = entry.isDirect();
|
||||
}
|
||||
|
||||
public String getPrincipalId()
|
||||
{
|
||||
return principalId;
|
||||
}
|
||||
|
||||
public String getPermission()
|
||||
{
|
||||
return permission;
|
||||
}
|
||||
|
||||
public boolean getDirect()
|
||||
{
|
||||
return direct;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((permission == null) ? 0 : permission.hashCode());
|
||||
result = prime * result + ((principalId == null) ? 0 : principalId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final CMISAccessControlEntry other = (CMISAccessControlEntry) obj;
|
||||
if (permission == null)
|
||||
{
|
||||
if (other.getPermission() != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!permission.equals(other.getPermission()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (principalId == null)
|
||||
{
|
||||
if (other.getPrincipalId() != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!principalId.equals(other.getPrincipalId()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
protected CmisACLType convertAclReportToCmisAclType(CMISAccessControlReport aclReport)
|
||||
{
|
||||
CmisACLType result = new CmisACLType();
|
||||
@@ -515,90 +384,54 @@ public class DMAbstractServicePort
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected CmisAllowableActionsType determineObjectAllowableActions(Object objectIdentifier) throws CmisException
|
||||
{
|
||||
if (objectIdentifier instanceof String)
|
||||
CMISTypeDefinition typeDef;
|
||||
try
|
||||
{
|
||||
objectIdentifier = cmisObjectsUtils.getIdentifierInstance(objectIdentifier.toString(), AlfrescoObjectType.ANY_OBJECT);
|
||||
if (objectIdentifier instanceof AssociationRef)
|
||||
{
|
||||
typeDef = cmisService.getTypeDefinition((AssociationRef) objectIdentifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (objectIdentifier instanceof Version)
|
||||
{
|
||||
objectIdentifier = ((Version) objectIdentifier).getFrozenStateNodeRef();
|
||||
}
|
||||
typeDef = cmisService.getTypeDefinition((NodeRef) objectIdentifier);
|
||||
}
|
||||
}
|
||||
if (objectIdentifier instanceof AssociationRef)
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
return determineRelationshipAllowableActions((AssociationRef) objectIdentifier);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
|
||||
switch (cmisObjectsUtils.determineObjectType(objectIdentifier.toString()))
|
||||
{
|
||||
case CMIS_DOCUMENT:
|
||||
{
|
||||
return determineDocumentAllowableActions((NodeRef) objectIdentifier);
|
||||
}
|
||||
case CMIS_FOLDER:
|
||||
{
|
||||
return determineFolderAllowableActions((NodeRef) objectIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: determinePolicyAllowableActions() when Policy functionality is ready
|
||||
throw cmisObjectsUtils.createCmisException("It is impossible to get Allowable actions for the specified Object", EnumServiceException.NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
private CmisAllowableActionsType determineBaseAllowableActions(NodeRef objectNodeReference)
|
||||
{
|
||||
CmisAllowableActionsType result = new CmisAllowableActionsType();
|
||||
result.setCanGetProperties(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_PROPERTIES) == AccessStatus.ALLOWED);
|
||||
result.setCanUpdateProperties(this.permissionService.hasPermission(objectNodeReference, PermissionService.WRITE_PROPERTIES) == AccessStatus.ALLOWED);
|
||||
result.setCanDeleteObject(this.permissionService.hasPermission(objectNodeReference, PermissionService.DELETE) == AccessStatus.ALLOWED);
|
||||
|
||||
// TODO: response.setCanAddPolicy(value);
|
||||
// TODO: response.setCanRemovePolicy(value);
|
||||
// TODO: response.setCanGetAppliedPolicies(value);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private CmisAllowableActionsType determineDocumentAllowableActions(NodeRef objectNodeReference)
|
||||
{
|
||||
CmisAllowableActionsType result = determineBaseAllowableActions(objectNodeReference);
|
||||
determineCommonFolderDocumentAllowableActions(objectNodeReference, result);
|
||||
result.setCanGetObjectParents(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_ASSOCIATIONS) == AccessStatus.ALLOWED);
|
||||
result.setCanGetContentStream(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_CONTENT) == AccessStatus.ALLOWED);
|
||||
result.setCanSetContentStream(this.permissionService.hasPermission(objectNodeReference, PermissionService.WRITE_CONTENT) == AccessStatus.ALLOWED);
|
||||
result.setCanCheckOut(this.permissionService.hasPermission(objectNodeReference, PermissionService.CHECK_OUT) == AccessStatus.ALLOWED);
|
||||
result.setCanCheckIn(this.permissionService.hasPermission(objectNodeReference, PermissionService.CHECK_IN) == AccessStatus.ALLOWED);
|
||||
result.setCanCancelCheckOut(this.permissionService.hasPermission(objectNodeReference, PermissionService.CANCEL_CHECK_OUT) == AccessStatus.ALLOWED);
|
||||
result.setCanDeleteContentStream(result.isCanUpdateProperties() && result.isCanSetContentStream());
|
||||
return result;
|
||||
}
|
||||
|
||||
private CmisAllowableActionsType determineFolderAllowableActions(NodeRef objectNodeReference)
|
||||
{
|
||||
CmisAllowableActionsType result = determineBaseAllowableActions(objectNodeReference);
|
||||
determineCommonFolderDocumentAllowableActions(objectNodeReference, result);
|
||||
|
||||
result.setCanGetChildren(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_CHILDREN) == AccessStatus.ALLOWED);
|
||||
result.setCanCreateDocument(this.permissionService.hasPermission(objectNodeReference, PermissionService.ADD_CHILDREN) == AccessStatus.ALLOWED);
|
||||
result.setCanGetDescendants(result.isCanGetChildren() && (this.permissionService.hasPermission(objectNodeReference, PermissionService.READ) == AccessStatus.ALLOWED));
|
||||
result.setCanDeleteTree(this.permissionService.hasPermission(objectNodeReference, PermissionService.DELETE_CHILDREN) == AccessStatus.ALLOWED);
|
||||
result.setCanGetFolderParent(result.isCanGetObjectRelationships());
|
||||
result.setCanCreateFolder(result.isCanCreateDocument());
|
||||
// TODO: response.setCanCreatePolicy(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void determineCommonFolderDocumentAllowableActions(NodeRef objectNodeReference, CmisAllowableActionsType allowableActions)
|
||||
{
|
||||
allowableActions.setCanAddObjectToFolder(this.permissionService.hasPermission(objectNodeReference, PermissionService.CREATE_ASSOCIATIONS) == AccessStatus.ALLOWED);
|
||||
allowableActions.setCanGetObjectRelationships(this.permissionService.hasPermission(objectNodeReference, PermissionService.READ_ASSOCIATIONS) == AccessStatus.ALLOWED);
|
||||
allowableActions.setCanMoveObject(allowableActions.isCanUpdateProperties() && allowableActions.isCanAddObjectToFolder());
|
||||
allowableActions.setCanRemoveObjectFromFolder(allowableActions.isCanUpdateProperties());
|
||||
allowableActions.setCanCreateRelationship(allowableActions.isCanAddObjectToFolder());
|
||||
}
|
||||
|
||||
private CmisAllowableActionsType determineRelationshipAllowableActions(AssociationRef association)
|
||||
{
|
||||
CmisAllowableActionsType result = new CmisAllowableActionsType();
|
||||
result.setCanDeleteObject(this.permissionService.hasPermission(association.getSourceRef(), PermissionService.DELETE_ASSOCIATIONS) == AccessStatus.ALLOWED);
|
||||
result.setCanGetObjectRelationships(this.permissionService.hasPermission(association.getSourceRef(), PermissionService.READ_ASSOCIATIONS) == AccessStatus.ALLOWED);
|
||||
for (Entry<CMISAllowedActionEnum, CMISActionEvaluator<? extends Object>> entry : typeDef.getActionEvaluators().entrySet())
|
||||
{
|
||||
PropertyDescriptor propertyDescriptor = ALLOWED_ACTION_ENUM_MAPPING.get(entry.getKey());
|
||||
if (propertyDescriptor != null)
|
||||
{
|
||||
// Let's assume that the evaluator will accept the object
|
||||
try
|
||||
{
|
||||
propertyDescriptor.getWriteMethod().invoke(result, new Boolean(((CMISActionEvaluator) entry.getValue()).isAllowed(objectIdentifier)));
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Exception setting allowable actions", e);
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Exception setting allowable actions", e);
|
||||
}
|
||||
catch (InvocationTargetException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Exception setting allowable actions", e.getTargetException());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@@ -26,7 +26,8 @@ package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import org.alfresco.cmis.CMISAccessControlFormatEnum;
|
||||
import org.alfresco.cmis.CMISAccessControlReport;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
@@ -42,7 +43,15 @@ public class DMAclServicePort extends DMAbstractServicePort implements ACLServic
|
||||
CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef object = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.ANY_OBJECT);
|
||||
NodeRef object;
|
||||
try
|
||||
{
|
||||
object = cmisService.getObject(objectId, NodeRef.class, true, false, false);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
return applyAclCarefully(object, addACEs, removeACEs, aclPropagation);
|
||||
}
|
||||
|
||||
@@ -52,10 +61,18 @@ public class DMAclServicePort extends DMAbstractServicePort implements ACLServic
|
||||
public CmisACLType getACL(String repositoryId, String objectId, Boolean onlyBasicPermissions, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef object = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.ANY_OBJECT);
|
||||
NodeRef nodeRef;
|
||||
try
|
||||
{
|
||||
nodeRef = cmisService.getReadableObject(objectId, NodeRef.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
CMISAccessControlFormatEnum permissionsKind = ((null == onlyBasicPermissions) || onlyBasicPermissions) ? (CMISAccessControlFormatEnum.CMIS_BASIC_PERMISSIONS)
|
||||
: (CMISAccessControlFormatEnum.REPOSITORY_SPECIFIC_PERMISSIONS);
|
||||
CMISAccessControlReport aclReport = cmisAclService.getAcl(object, permissionsKind);
|
||||
CMISAccessControlReport aclReport = cmisAclService.getAcl(nodeRef, permissionsKind);
|
||||
return convertAclReportToCmisAclType(aclReport);
|
||||
}
|
||||
}
|
||||
|
@@ -26,7 +26,6 @@ package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -43,8 +42,9 @@ import org.alfresco.cmis.CMISQueryOptions;
|
||||
import org.alfresco.cmis.CMISResultSet;
|
||||
import org.alfresco.cmis.CMISResultSetColumn;
|
||||
import org.alfresco.cmis.CMISResultSetRow;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
|
||||
/**
|
||||
* Port for Discovery service.
|
||||
@@ -118,7 +118,15 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
|
||||
|
||||
CmisObjectType object = new CmisObjectType();
|
||||
object.setProperties(properties);
|
||||
Object identifier = cmisObjectsUtils.getIdentifierInstance((String) values.get(CMISDictionaryModel.PROP_OBJECT_ID), AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT);
|
||||
Object identifier;
|
||||
try
|
||||
{
|
||||
identifier = cmisService.getReadableObject((String) values.get(CMISDictionaryModel.PROP_OBJECT_ID), Object.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
if (includeAllowableActions)
|
||||
{
|
||||
object.setAllowableActions(determineObjectAllowableActions(identifier));
|
||||
@@ -175,26 +183,14 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
|
||||
filter = CMISDictionaryModel.PROP_OBJECT_ID;
|
||||
}
|
||||
|
||||
if (changeToken != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Long.parseLong(changeToken);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Invalid changeLogToken was specified", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
CMISChangeLog changeLog = null;
|
||||
try
|
||||
{
|
||||
changeLog = cmisChangeLogService.getChangeLogEvents(changeToken, maxAmount);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(e.getMessage(), EnumServiceException.STORAGE);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
if (null == objects.value)
|
||||
{
|
||||
@@ -230,10 +226,10 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
|
||||
CmisObjectType object = new CmisObjectType();
|
||||
CmisPropertiesType propertiesType = new CmisPropertiesType();
|
||||
object.setProperties(propertiesType);
|
||||
propertiesType.getProperty().add(propertiesUtil.createProperty(CMISDictionaryModel.PROP_OBJECT_ID, CMISDataTypeEnum.ID, event.getNode()));
|
||||
if (nodeService.exists(event.getNode()) && includeAce)
|
||||
propertiesType.getProperty().add(propertiesUtil.createProperty(CMISDictionaryModel.PROP_OBJECT_ID, CMISDataTypeEnum.ID, event.getObjectId()));
|
||||
if (nodeService.exists(event.getChangedNode()) && includeAce)
|
||||
{
|
||||
appendWithAce(event.getNode(), object);
|
||||
appendWithAce(event.getChangedNode(), object);
|
||||
}
|
||||
CmisChangeEventType changeInfo = new CmisChangeEventType();
|
||||
XMLGregorianCalendar modificationDate = propertiesUtil.convert(event.getChangeTime());
|
||||
|
@@ -26,10 +26,8 @@ package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
|
||||
/**
|
||||
* Port for Multi-Filing service.
|
||||
@@ -51,25 +49,13 @@ public class DMMultiFilingServicePort extends DMAbstractServicePort implements M
|
||||
public void addObjectToFolder(String repositoryId, String objectId, String folderId, Boolean allVersions, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef objectNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef parentFolderNodeRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
CMISTypeDefinition objectType = cmisDictionaryService.findType(propertiesUtil.getProperty(objectNodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, (String) null));
|
||||
CMISTypeDefinition folderType = cmisDictionaryService.findType(propertiesUtil.getProperty(parentFolderNodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, (String) null));
|
||||
if (folderType == null)
|
||||
try
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Type of the specified parent folder can't be resovled", EnumServiceException.RUNTIME);
|
||||
cmisService.addObjectToFolder(objectId, folderId);
|
||||
}
|
||||
// FIXME [BUG]: folderType.getAllowedTargetTypes() MUST be changed on folderType.getAllowedChildObjectTypeIds()
|
||||
if (!folderType.getAllowedTargetTypes().isEmpty() && !folderType.getAllowedTargetTypes().contains(objectType))
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("The Object of '" + objectType.getTypeId() + "' Type can't be child of Folder of '" + folderType.getTypeId() + "' Type"),
|
||||
EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
if (!cmisObjectsUtils.addObjectToFolder(objectNodeRef, parentFolderNodeRef))
|
||||
{
|
||||
Throwable exception = cmisObjectsUtils.getLastOperationException();
|
||||
throw cmisObjectsUtils.createCmisException(("Can't add specified Object to specified Folder. Cause exception message: " + exception.toString()),
|
||||
EnumServiceException.STORAGE, exception);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,43 +70,13 @@ public class DMMultiFilingServicePort extends DMAbstractServicePort implements M
|
||||
public void removeObjectFromFolder(String repositoryId, String objectId, String folderId, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef objectNodeReference = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef folderNodeReference = checkAndReceiveFolderIdentifier(folderId);
|
||||
// FIXME [BUG]: if Document is Multi-Filled then removing this Object from Primary Parent Folder MUST treat to determine Primary Parent for Document from other Parent
|
||||
// Folders
|
||||
checkObjectChildParentRelationships(objectNodeReference, folderNodeReference);
|
||||
if (!cmisObjectsUtils.removeObject(objectNodeReference, folderNodeReference))
|
||||
{
|
||||
Throwable exception = cmisObjectsUtils.getLastOperationException();
|
||||
if (null != exception)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Can't remove specified Object from specified Folder. Cause exception message: " + exception.toString()),
|
||||
EnumServiceException.STORAGE, exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Can't remove specified Object from specified Folder", EnumServiceException.STORAGE, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private NodeRef checkAndReceiveFolderIdentifier(String folderIdentifier) throws CmisException
|
||||
{
|
||||
try
|
||||
{
|
||||
return cmisObjectsUtils.getIdentifierInstance(folderIdentifier, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
cmisService.removeObjectFromFolder(objectId, folderId);
|
||||
}
|
||||
catch (Throwable e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Unfiling is not supported. An Object can't be deleted from all Folders", EnumServiceException.NOT_SUPPORTED, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkObjectChildParentRelationships(NodeRef objectNodeReference, NodeRef folderNodeReference) throws CmisException
|
||||
{
|
||||
if (cmisObjectsUtils.isPrimaryObjectParent(folderNodeReference, objectNodeReference))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Unfiling is not supported. Use deleteObject() Service instead", EnumServiceException.NOT_SUPPORTED);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -15,11 +15,11 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
@@ -29,17 +29,16 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISTypesFilterEnum;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.springframework.extensions.surf.util.Pair;
|
||||
|
||||
/**
|
||||
* Port for navigation service
|
||||
@@ -55,9 +54,6 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
|
||||
private static final String FILTER_TOKENS_DELIMETER = ", ";
|
||||
|
||||
private static final Pattern ORDER_BY_CLAUSE_MASK = Pattern.compile("^( )*([\\p{Alnum}_]+(( )+((ASC)|(DESC))){1}){1}((,){1}( )*[\\p{Alnum}_]+(( )+((ASC)|(DESC))){1})*( )*$",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
|
||||
/**
|
||||
* Gets the private working copies of checked-out objects that the user is allowed to update.
|
||||
*
|
||||
@@ -71,35 +67,36 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
checkRepositoryId(repositoryId);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
|
||||
NodeRef folderRef = null;
|
||||
if ((folderId != null) && !folderId.equals(""))
|
||||
try
|
||||
{
|
||||
folderRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
}
|
||||
NodeRef folderRef = null;
|
||||
if ((folderId != null) && !folderId.equals(""))
|
||||
{
|
||||
folderRef = cmisService.getFolder(folderId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
List<Pair<String, Boolean>> orderingFields = null;
|
||||
if ((orderBy != null) && !orderBy.equals(""))
|
||||
NodeRef[] nodeRefs = cmisService.getCheckedOut(AuthenticationUtil.getFullyAuthenticatedUser(), folderRef,
|
||||
(folderRef == null), orderBy);
|
||||
Cursor cursor = createCursor(nodeRefs.length, skipCount, maxItems);
|
||||
|
||||
CmisObjectListType result = new CmisObjectListType();
|
||||
List<CmisObjectType> resultListing = result.getObjects();
|
||||
|
||||
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
|
||||
{
|
||||
resultListing.add(createCmisObject(nodeRefs[index], propertyFilter, includeAllowableActions,
|
||||
renditionFilter));
|
||||
}
|
||||
result.setHasMoreItems(new Boolean(cursor.getEndRow() < (nodeRefs.length - 1)));
|
||||
|
||||
// TODO: includeAllowableActions, includeRelationships, renditions
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
orderingFields = checkAndParseOrderByClause(orderBy);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
|
||||
// TODO: Ordering functionality SHOULD be moved to getChildren service method
|
||||
NodeRef[] nodeRefs = cmisService.getCheckedOut(AuthenticationUtil.getFullyAuthenticatedUser(), folderRef, (folderRef == null));
|
||||
Cursor cursor = createCursor(nodeRefs.length, skipCount, maxItems);
|
||||
|
||||
CmisObjectListType result = new CmisObjectListType();
|
||||
List<CmisObjectType> resultListing = result.getObjects();
|
||||
|
||||
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
|
||||
{
|
||||
resultListing.add(createCmisObject(nodeRefs[index].toString(), propertyFilter, includeAllowableActions, renditionFilter));
|
||||
}
|
||||
result.setHasMoreItems(new Boolean(cursor.getEndRow() < (nodeRefs.length - 1)));
|
||||
|
||||
// TODO: includeAllowableActions, includeRelationships, renditions
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,46 +108,48 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
* @return collection of CmisObjectType and boolean hasMoreItems
|
||||
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, FILTER_NOT_VALID)
|
||||
*/
|
||||
public CmisObjectInFolderListType getChildren(String repositoryId, String folderId, String filter, String orderBy, Boolean includeAllowableActions,
|
||||
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegments, BigInteger maxItems, BigInteger skipCount,
|
||||
CmisExtensionType extension) throws CmisException
|
||||
public CmisObjectInFolderListType getChildren(String repositoryId, String folderId, String filter, String orderBy,
|
||||
Boolean includeAllowableActions, EnumIncludeRelationships includeRelationships, String renditionFilter,
|
||||
Boolean includePathSegments, BigInteger maxItems, BigInteger skipCount, CmisExtensionType extension)
|
||||
throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
|
||||
NodeRef folderNodeRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
List<Pair<String, Boolean>> orderingFields = null;
|
||||
if ((orderBy != null) && !orderBy.equals(""))
|
||||
try
|
||||
{
|
||||
orderingFields = checkAndParseOrderByClause(orderBy);
|
||||
}
|
||||
NodeRef folderNodeRef = cmisService.getFolder(folderId);
|
||||
|
||||
// TODO: Ordering functionality SHOULD be moved to getChildren service method
|
||||
NodeRef[] listing = cmisService.getChildren(folderNodeRef, CMISTypesFilterEnum.ANY);
|
||||
NodeRef[] listing = cmisService.getChildren(folderNodeRef, CMISTypesFilterEnum.ANY, orderBy);
|
||||
|
||||
CmisObjectInFolderListType result = new CmisObjectInFolderListType();
|
||||
CmisObjectInFolderListType result = new CmisObjectInFolderListType();
|
||||
|
||||
Cursor cursor = createCursor(listing.length, skipCount, maxItems);
|
||||
Cursor cursor = createCursor(listing.length, skipCount, maxItems);
|
||||
|
||||
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
|
||||
{
|
||||
CmisObjectType cmisObject = createCmisObject(listing[index].toString(), propertyFilter, includeAllowableActions, renditionFilter);
|
||||
CmisObjectInFolderType cmisObjectInFolder = new CmisObjectInFolderType();
|
||||
cmisObjectInFolder.setObject(cmisObject);
|
||||
if (includePathSegments != null && includePathSegments)
|
||||
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
|
||||
{
|
||||
cmisObjectInFolder.setPathSegment(propertiesUtil.getProperty(listing[index], CMISDictionaryModel.PROP_NAME, ""));
|
||||
CmisObjectType cmisObject = createCmisObject(listing[index], propertyFilter, includeAllowableActions,
|
||||
renditionFilter);
|
||||
CmisObjectInFolderType cmisObjectInFolder = new CmisObjectInFolderType();
|
||||
cmisObjectInFolder.setObject(cmisObject);
|
||||
if (includePathSegments != null && includePathSegments)
|
||||
{
|
||||
cmisObjectInFolder.setPathSegment(propertiesUtil.getProperty(listing[index],
|
||||
CMISDictionaryModel.PROP_NAME, ""));
|
||||
}
|
||||
result.getObjects().add(cmisObjectInFolder);
|
||||
}
|
||||
result.getObjects().add(cmisObjectInFolder);
|
||||
|
||||
result.setHasMoreItems(cursor.getEndRow() < (listing.length - 1));
|
||||
result.setNumItems(BigInteger.valueOf(listing.length));
|
||||
|
||||
// TODO: Process includeRelationships, includeACL
|
||||
return result;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
|
||||
result.setHasMoreItems(cursor.getEndRow() < (listing.length - 1));
|
||||
result.setNumItems(BigInteger.valueOf(listing.length));
|
||||
|
||||
// TODO: Process includeRelationships, includeACL
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,7 +164,7 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
public List<CmisObjectInFolderContainerType> getDescendants(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions,
|
||||
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegments, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
CmisObjectInFolderContainerType objectInFolderContainerType = getDescedantsTree(repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships,
|
||||
CmisObjectInFolderContainerType objectInFolderContainerType = getDescendantsTree(repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships,
|
||||
renditionFilter, includePathSegments, CMISTypesFilterEnum.ANY);
|
||||
return objectInFolderContainerType.getChildren();
|
||||
}
|
||||
@@ -182,7 +181,7 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
public List<CmisObjectInFolderContainerType> getFolderTree(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions,
|
||||
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegments, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
CmisObjectInFolderContainerType objectInFolderContainerType = getDescedantsTree(repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships,
|
||||
CmisObjectInFolderContainerType objectInFolderContainerType = getDescendantsTree(repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships,
|
||||
renditionFilter, includePathSegments, CMISTypesFilterEnum.FOLDERS);
|
||||
return objectInFolderContainerType.getChildren();
|
||||
}
|
||||
@@ -211,9 +210,17 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
}
|
||||
}
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
NodeRef parentRef = receiveParent(folderId);
|
||||
NodeRef parentRef;
|
||||
try
|
||||
{
|
||||
parentRef = cmisService.getFolderParent(folderId);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
|
||||
CmisObjectType result = createCmisObject(parentRef, propertyFilter, false, null);
|
||||
// TODO: It is not clear whether ACL etc should be returned
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -231,7 +238,15 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
checkRepositoryId(repositoryId);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
|
||||
NodeRef childNode = (NodeRef) cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef childNode;
|
||||
try
|
||||
{
|
||||
childNode = (NodeRef) cmisService.getReadableObject(objectId, NodeRef.class);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
List<NodeRef> parents = receiveObjectParents(childNode);
|
||||
|
||||
List<CmisObjectParentsType> result = new ArrayList<CmisObjectParentsType>();
|
||||
@@ -252,7 +267,7 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
return result;
|
||||
}
|
||||
|
||||
private CmisObjectInFolderContainerType getDescedantsTree(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions,
|
||||
private CmisObjectInFolderContainerType getDescendantsTree(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions,
|
||||
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegments, CMISTypesFilterEnum types) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
@@ -262,34 +277,43 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
long maxDepth = depth.longValue();
|
||||
checkDepthParameter(depth);
|
||||
|
||||
NodeRef folderNodeRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
Stack<RecursiveElement> descedantsStack = new Stack<RecursiveElement>();
|
||||
CmisObjectInFolderContainerType objectInFolderContainer = createObjectInFolderContainer(folderNodeRef, propertyFilter, includeAllowableActions, includeRelationships,
|
||||
renditionFilter, includePathSegments);
|
||||
NodeRef[] children = cmisService.getChildren(folderNodeRef, types);
|
||||
for (NodeRef childRef : children)
|
||||
try
|
||||
{
|
||||
descedantsStack.push(new RecursiveElement(objectInFolderContainer, 1, childRef));
|
||||
}
|
||||
while (!descedantsStack.isEmpty())
|
||||
{
|
||||
RecursiveElement element = descedantsStack.pop();
|
||||
CmisObjectInFolderContainerType currentContainer = createObjectInFolderContainer(element.getCurrentNodeRef(), propertyFilter, includeAllowableActions,
|
||||
includeRelationships, renditionFilter, includePathSegments);
|
||||
element.getParentContainerType().getChildren().add(currentContainer);
|
||||
if (element.getDepth() <= maxDepth)
|
||||
NodeRef folderNodeRef = cmisService.getFolder(folderId);
|
||||
Stack<RecursiveElement> descedantsStack = new Stack<RecursiveElement>();
|
||||
CmisObjectInFolderContainerType objectInFolderContainer = createObjectInFolderContainer(folderNodeRef,
|
||||
propertyFilter, includeAllowableActions, includeRelationships, renditionFilter, includePathSegments);
|
||||
NodeRef[] children = cmisService.getChildren(folderNodeRef, types, null);
|
||||
for (NodeRef childRef : children)
|
||||
{
|
||||
children = cmisService.getChildren(element.getCurrentNodeRef(), types);
|
||||
if (children != null)
|
||||
descedantsStack.push(new RecursiveElement(objectInFolderContainer, 1, childRef));
|
||||
}
|
||||
while (!descedantsStack.isEmpty())
|
||||
{
|
||||
RecursiveElement element = descedantsStack.pop();
|
||||
CmisObjectInFolderContainerType currentContainer = createObjectInFolderContainer(element
|
||||
.getCurrentNodeRef(), propertyFilter, includeAllowableActions, includeRelationships,
|
||||
renditionFilter, includePathSegments);
|
||||
element.getParentContainerType().getChildren().add(currentContainer);
|
||||
if (element.getDepth() <= maxDepth)
|
||||
{
|
||||
for (NodeRef childRef : children)
|
||||
children = cmisService.getChildren(element.getCurrentNodeRef(), types, null);
|
||||
if (children != null)
|
||||
{
|
||||
descedantsStack.push(new RecursiveElement(currentContainer, element.getDepth() + 1, childRef));
|
||||
for (NodeRef childRef : children)
|
||||
{
|
||||
descedantsStack.push(new RecursiveElement(currentContainer, element.getDepth() + 1,
|
||||
childRef));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return objectInFolderContainer;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
return objectInFolderContainer;
|
||||
}
|
||||
|
||||
private CmisObjectInFolderContainerType createObjectInFolderContainer(NodeRef nodeRef, PropertyFilter filter, Boolean includeAllowableActions,
|
||||
@@ -311,56 +335,15 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Pair<String, Boolean>> checkAndParseOrderByClause(String orderByClause) throws CmisException
|
||||
{
|
||||
List<Pair<String, Boolean>> result = new LinkedList<Pair<String, Boolean>>();
|
||||
|
||||
if (!ORDER_BY_CLAUSE_MASK.matcher(orderByClause).matches())
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("\"" + orderByClause + "\" Order By Clause is invalid!"), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
for (String token : orderByClause.split(","))
|
||||
{
|
||||
token = token.trim();
|
||||
|
||||
String[] direction = token.split(" ");
|
||||
String fieldName = direction[0];
|
||||
result.add(new Pair<String, Boolean>(fieldName, direction[direction.length - 1].toLowerCase().equals("asc")));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private NodeRef receiveParent(String targetChildIdentifier) throws CmisException
|
||||
{
|
||||
if (cmisService.getDefaultRootNodeRef().toString().equals(targetChildIdentifier))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Root Folder has no parents", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
NodeRef identifierInstance = (NodeRef) cmisObjectsUtils.getIdentifierInstance(targetChildIdentifier, AlfrescoObjectType.FOLDER_OBJECT);
|
||||
return receiveNextParentNodeReference(identifierInstance, new LinkedList<NodeRef>());
|
||||
}
|
||||
|
||||
private void checkDepthParameter(BigInteger depth) throws CmisException
|
||||
{
|
||||
if (depth.equals(BigInteger.ZERO) || (depth.compareTo(FULL_DESCENDANTS_HIERARCHY_CONDITION) < EQUALS_CONDITION_VALUE))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("The specified descendants depth is not valid. Valid depth values are: -1 (full hierarchy), N > 0",
|
||||
throw ExceptionUtil.createCmisException("The specified descendants depth is not valid. Valid depth values are: -1 (full hierarchy), N > 0",
|
||||
EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
private NodeRef receiveNextParentNodeReference(NodeRef currentParent, List<NodeRef> parents)
|
||||
{
|
||||
currentParent = nodeService.getPrimaryParent(currentParent).getParentRef();
|
||||
if (currentParent != null)
|
||||
{
|
||||
parents.add(currentParent);
|
||||
}
|
||||
return currentParent;
|
||||
}
|
||||
|
||||
private List<NodeRef> receiveObjectParents(NodeRef objectId) throws CmisException
|
||||
{
|
||||
List<NodeRef> parents = new LinkedList<NodeRef>();
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,8 @@ import java.util.List;
|
||||
|
||||
import javax.xml.ws.Holder;
|
||||
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
|
||||
@javax.jws.WebService(name = "PolicyServicePort", serviceName = "PolicyServicePort", portName = "PolicyServicePort", targetNamespace = "http://docs.oasis-open.org/ns/cmis/ws/200908/", endpointInterface = "org.alfresco.repo.cmis.ws.PolicyServicePort")
|
||||
public class DMPolicyServicePort extends DMAbstractServicePort implements PolicyServicePort
|
||||
{
|
||||
@@ -43,7 +45,7 @@ public class DMPolicyServicePort extends DMAbstractServicePort implements Policy
|
||||
*/
|
||||
public void applyPolicy(String repositoryId, String policyId, String objectId, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +56,7 @@ public class DMPolicyServicePort extends DMAbstractServicePort implements Policy
|
||||
*/
|
||||
public List<CmisObjectType> getAppliedPolicies(String repositoryId, String objectId, String filter, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,6 +69,6 @@ public class DMPolicyServicePort extends DMAbstractServicePort implements Policy
|
||||
*/
|
||||
public void removePolicy(String repositoryId, String policyId, String objectId, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
|
||||
}
|
||||
}
|
||||
|
@@ -25,18 +25,17 @@
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.CMISScope;
|
||||
import org.alfresco.cmis.CMISRelationshipDirectionEnum;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
|
||||
/**
|
||||
* Port for relationship service
|
||||
@@ -46,11 +45,13 @@ import org.alfresco.service.namespace.QNamePattern;
|
||||
@javax.jws.WebService(name = "RelationshipServicePort", serviceName = "RelationshipService", portName = "RelationshipServicePort", targetNamespace = "http://docs.oasis-open.org/ns/cmis/ws/200908/", endpointInterface = "org.alfresco.repo.cmis.ws.RelationshipServicePort")
|
||||
public class DMRelationshipServicePort extends DMAbstractServicePort implements RelationshipServicePort
|
||||
{
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
private static final Map<EnumRelationshipDirection, CMISRelationshipDirectionEnum> RELATIONSHIP_DIRECTION_MAPPING;
|
||||
static
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
RELATIONSHIP_DIRECTION_MAPPING = new HashMap<EnumRelationshipDirection, CMISRelationshipDirectionEnum>(5);
|
||||
RELATIONSHIP_DIRECTION_MAPPING.put(EnumRelationshipDirection.SOURCE, CMISRelationshipDirectionEnum.SOURCE);
|
||||
RELATIONSHIP_DIRECTION_MAPPING.put(EnumRelationshipDirection.TARGET, CMISRelationshipDirectionEnum.TARGET);
|
||||
RELATIONSHIP_DIRECTION_MAPPING.put(EnumRelationshipDirection.EITHER, CMISRelationshipDirectionEnum.BOTH);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,31 +67,25 @@ public class DMRelationshipServicePort extends DMAbstractServicePort implements
|
||||
String typeId, String filter, Boolean includeAllowableActions, BigInteger maxItems, BigInteger skipCount, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef objectNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT);
|
||||
if (null == includeSubRelationshipTypes)
|
||||
if ((null == objectId) || "".equals(objectId) || !NodeRef.isNodeRef(objectId))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("includeSubRelationshipTypes input parameter is required", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException(("Object with Id='" + objectId + "' is not exist!"), EnumServiceException.OBJECT_NOT_FOUND);
|
||||
}
|
||||
relationshipDirection = (null != relationshipDirection) ? relationshipDirection : EnumRelationshipDirection.SOURCE;
|
||||
skipCount = (null != skipCount) ? skipCount : BigInteger.ZERO;
|
||||
maxItems = (null != maxItems) ? maxItems : BigInteger.ZERO;
|
||||
QName associationType = null;
|
||||
if ((null != typeId) && !"".equals(typeId))
|
||||
{
|
||||
CMISTypeDefinition cmisTypeDef = cmisDictionaryService.findType(typeId);
|
||||
associationType = cmisTypeDef.getTypeId().getQName();
|
||||
}
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
List<AssociationRef> assocs = null;
|
||||
try
|
||||
{
|
||||
assocs = cmisObjectsUtils.receiveAssociations(objectNodeRef, new RelationshipTypeFilter(associationType, includeSubRelationshipTypes), relationshipDirection);
|
||||
CMISTypeDefinition relDef = (null != typeId) ? (cmisService.getTypeDefinition(typeId)):(null);
|
||||
NodeRef nodeRef = cmisService.getReadableObject(objectId, NodeRef.class);
|
||||
AssociationRef[] assocs = cmisService.getRelationships(nodeRef, relDef, includeSubRelationshipTypes != null && includeSubRelationshipTypes,
|
||||
relationshipDirection == null ? CMISRelationshipDirectionEnum.SOURCE : RELATIONSHIP_DIRECTION_MAPPING.get(relationshipDirection));
|
||||
skipCount = (null != skipCount) ? skipCount : BigInteger.ZERO;
|
||||
maxItems = (null != maxItems) ? maxItems : BigInteger.ZERO;
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
return createResult(propertyFilter, includeAllowableActions, assocs, skipCount, maxItems);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Can't receive associations", e);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
return createResult(propertyFilter, includeAllowableActions, assocs.toArray(), skipCount, maxItems);
|
||||
}
|
||||
|
||||
private CmisObjectListType createResult(PropertyFilter filter, boolean includeAllowableActions, Object[] sourceArray, BigInteger skipCount, BigInteger maxItems)
|
||||
@@ -100,39 +95,10 @@ public class DMRelationshipServicePort extends DMAbstractServicePort implements
|
||||
CmisObjectListType result = new CmisObjectListType();
|
||||
for (int i = cursor.getStartRow(); i <= cursor.getEndRow(); i++)
|
||||
{
|
||||
result.getObjects().add(createCmisObject(sourceArray[i].toString(), filter, includeAllowableActions, null));
|
||||
result.getObjects().add(createCmisObject(sourceArray[i], filter, includeAllowableActions, null));
|
||||
}
|
||||
result.setHasMoreItems(cursor.getEndRow() < sourceArray.length);
|
||||
result.setNumItems(BigInteger.valueOf(cursor.getPageSize()));
|
||||
return result;
|
||||
}
|
||||
|
||||
private class RelationshipTypeFilter implements QNamePattern
|
||||
{
|
||||
private boolean includeSubtypes;
|
||||
private QName relationshipType;
|
||||
|
||||
public RelationshipTypeFilter(QName ralationshipType, boolean includeSubtypes)
|
||||
{
|
||||
this.relationshipType = ralationshipType;
|
||||
this.includeSubtypes = includeSubtypes;
|
||||
}
|
||||
|
||||
public boolean isMatch(QName qname)
|
||||
{
|
||||
if (relationshipType == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (includeSubtypes)
|
||||
{
|
||||
return null != dictionaryService.getAssociation(qname);
|
||||
}
|
||||
else
|
||||
{
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForClass(qname, CMISScope.RELATIONSHIP);
|
||||
return typeDef != null && relationshipType.equals(qname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -33,7 +33,6 @@ import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.alfresco.cmis.CMISAclCapabilityEnum;
|
||||
import org.alfresco.cmis.CMISAclPropagationEnum;
|
||||
@@ -50,8 +49,10 @@ import org.alfresco.cmis.CMISPermissionDefinition;
|
||||
import org.alfresco.cmis.CMISPermissionMapping;
|
||||
import org.alfresco.cmis.CMISPropertyDefinition;
|
||||
import org.alfresco.cmis.CMISQueryEnum;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.cmis.CMISUpdatabilityEnum;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.web.util.paging.Cursor;
|
||||
import org.alfresco.service.descriptor.Descriptor;
|
||||
|
||||
@@ -324,7 +325,7 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(type.getLabel(), EnumServiceException.OBJECT_NOT_FOUND);
|
||||
throw ExceptionUtil.createCmisException(type.getLabel(), EnumServiceException.OBJECT_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -379,7 +380,7 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
{
|
||||
if (typeDef == null)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Type not found", EnumServiceException.OBJECT_NOT_FOUND);
|
||||
throw ExceptionUtil.createCmisException("Type not found", EnumServiceException.OBJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
CmisTypeDefinitionType result = null;
|
||||
@@ -439,7 +440,7 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
result = relationshipDefinitionType;
|
||||
break;
|
||||
case UNKNOWN:
|
||||
throw cmisObjectsUtils.createCmisException("Unknown CMIS Type", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException("Unknown CMIS Type", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -572,7 +573,15 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
Collection<CMISTypeDefinition> typeDefs = getBaseTypesCollection(typeId, true);
|
||||
Collection<CMISTypeDefinition> typeDefs;
|
||||
try
|
||||
{
|
||||
typeDefs = typeId == null ? cmisService.getBaseTypes() : cmisService.getTypeDefinition(typeId).getSubTypes(false);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
// skip
|
||||
Cursor cursor = createCursor(typeDefs.size(), skipCount, maxItems);
|
||||
Iterator<CMISTypeDefinition> iterTypeDefs = typeDefs.iterator();
|
||||
@@ -593,7 +602,7 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
}
|
||||
else
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Subtypes collection is corrupted. Type id: " + typeId), EnumServiceException.STORAGE);
|
||||
throw ExceptionUtil.createCmisException(("Subtypes collection is corrupted. Type id: " + typeId), EnumServiceException.STORAGE);
|
||||
}
|
||||
}
|
||||
result.setHasMoreItems(((maxItems == null) || (0 == maxItems.intValue())) ? (false) : ((cursor.getEndRow() < (typeDefs.size() - 1))));
|
||||
@@ -614,11 +623,11 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
CMISTypeDefinition typeDef;
|
||||
try
|
||||
{
|
||||
typeDef = cmisDictionaryService.findType(typeId);
|
||||
typeDef = cmisService.getTypeDefinition(typeId);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(e.toString(), EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
return getCmisTypeDefinition(typeDef, true);
|
||||
}
|
||||
@@ -634,39 +643,39 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
long depthLong = (null == depth) ? (-1) : (depth.longValue());
|
||||
long depthLong = (null == depth || null == typeId) ? (-1) : (depth.longValue());
|
||||
if (0 == depthLong)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Depth parameter equal to '0' have no sence", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException("Invalid depth '0'", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
boolean includePropertyDefsBool = (null == includePropertyDefinitions) ? (false) : (includePropertyDefinitions);
|
||||
List<CmisTypeContainer> result = new LinkedList<CmisTypeContainer>();
|
||||
Queue<TypeElement> typesQueue = new LinkedList<TypeElement>();
|
||||
Collection<CMISTypeDefinition> typeDefs = getBaseTypesCollection(typeId, false);
|
||||
for (CMISTypeDefinition typeDef : typeDefs)
|
||||
CMISTypeDefinition typeDef;
|
||||
try
|
||||
{
|
||||
typesQueue.add(new TypeElement(0L, typeDef, createTypeContainer(typeDef, includePropertyDefsBool)));
|
||||
typeDef = typeId == null ? null : cmisService.getTypeDefinition(typeId);
|
||||
}
|
||||
for (TypeElement element = typesQueue.peek(); !typesQueue.isEmpty(); element = (typeDefs.isEmpty()) ? (null) : (typesQueue.peek()))
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
typesQueue.poll();
|
||||
result.add(element.getContainer());
|
||||
long nextLevel = element.getLevel() + 1;
|
||||
Collection<CMISTypeDefinition> subTypes = element.getTypeDefinition().getSubTypes(false);
|
||||
if (null != subTypes)
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
getTypeDescendants(typeDef, result, includePropertyDefinitions != null && includePropertyDefinitions, 1, depthLong);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void getTypeDescendants(CMISTypeDefinition parent, List<CmisTypeContainer> result, boolean includePropertyDefs, long depth, long maxDepth) throws CmisException
|
||||
{
|
||||
Collection<CMISTypeDefinition> subtypes = parent == null ? cmisService.getBaseTypes() : parent.getSubTypes(false);
|
||||
for (CMISTypeDefinition typeDef : subtypes)
|
||||
{
|
||||
result.add(createTypeContainer(typeDef, includePropertyDefs));
|
||||
}
|
||||
if (maxDepth == -1 || depth + 1 <= maxDepth)
|
||||
{
|
||||
for (CMISTypeDefinition typeDef : subtypes)
|
||||
{
|
||||
for (CMISTypeDefinition typeDef : subTypes)
|
||||
{
|
||||
CmisTypeContainer childContainer = createTypeContainer(typeDef, includePropertyDefsBool);
|
||||
if ((-1 == depthLong) || (nextLevel <= depthLong))
|
||||
{
|
||||
element.getContainer().getChildren().add(childContainer);
|
||||
typesQueue.add(new TypeElement(nextLevel, typeDef, childContainer));
|
||||
}
|
||||
}
|
||||
getTypeDescendants(typeDef, result, includePropertyDefs, depth + 1, maxDepth);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private CmisTypeContainer createTypeContainer(CMISTypeDefinition parentType, boolean includeProperties) throws CmisException
|
||||
@@ -675,70 +684,4 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
|
||||
result.setType(getCmisTypeDefinition(parentType, includeProperties));
|
||||
return result;
|
||||
}
|
||||
|
||||
private class TypeElement
|
||||
{
|
||||
private long level;
|
||||
private CMISTypeDefinition typeDefinition;
|
||||
private CmisTypeContainer container;
|
||||
|
||||
public TypeElement(long level, CMISTypeDefinition typeDefinition, CmisTypeContainer container)
|
||||
{
|
||||
this.level = level;
|
||||
this.typeDefinition = typeDefinition;
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
public long getLevel()
|
||||
{
|
||||
return level;
|
||||
}
|
||||
|
||||
public CMISTypeDefinition getTypeDefinition()
|
||||
{
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
public CmisTypeContainer getContainer()
|
||||
{
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<CMISTypeDefinition> getBaseTypesCollection(String typeId, boolean includeSubtypes) throws CmisException
|
||||
{
|
||||
Collection<CMISTypeDefinition> typeDefs = new LinkedList<CMISTypeDefinition>();
|
||||
if ((null == typeId) || "".equals(typeId))
|
||||
{
|
||||
typeDefs = cmisDictionaryService.getBaseTypes();
|
||||
}
|
||||
else
|
||||
{
|
||||
CMISTypeDefinition typeDef = null;
|
||||
try
|
||||
{
|
||||
typeDef = cmisDictionaryService.findType(typeId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(e.toString(), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
if (null == typeDef)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Invalid type id: \"" + typeId + "\""), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
typeDefs.add(typeDef);
|
||||
|
||||
if (includeSubtypes)
|
||||
{
|
||||
Collection<CMISTypeDefinition> subTypes = typeDef.getSubTypes(false);
|
||||
if (null != subTypes)
|
||||
{
|
||||
typeDefs.addAll(subTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return typeDefs;
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -15,16 +15,16 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws;
|
||||
|
||||
import org.alfresco.repo.cmis.ws.utils.CmisObjectsUtils;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -40,13 +40,6 @@ public class DMServicePortThrowsAdvice implements ThrowsAdvice
|
||||
{
|
||||
private static final Log LOGGER = LogFactory.getLog("org.alfresco.repo.cmis.ws");
|
||||
|
||||
private CmisObjectsUtils cmisObjectsUtils;
|
||||
|
||||
public void setCmisObjectsUtils(CmisObjectsUtils cmisObjectsUtils)
|
||||
{
|
||||
this.cmisObjectsUtils = cmisObjectsUtils;
|
||||
}
|
||||
|
||||
public void afterThrowing(AccessDeniedException e) throws CmisException
|
||||
{
|
||||
if (LOGGER.isInfoEnabled())
|
||||
@@ -54,7 +47,7 @@ public class DMServicePortThrowsAdvice implements ThrowsAdvice
|
||||
LOGGER.error(e.toString(), e);
|
||||
}
|
||||
|
||||
throw cmisObjectsUtils.createCmisException(("Access denied. Message: " + e.toString()), e);
|
||||
throw ExceptionUtil.createCmisException(("Access denied. Message: " + e.toString()), e);
|
||||
}
|
||||
|
||||
public void afterThrowing(java.lang.RuntimeException e) throws CmisException
|
||||
@@ -64,7 +57,7 @@ public class DMServicePortThrowsAdvice implements ThrowsAdvice
|
||||
LOGGER.error(e.toString(), e);
|
||||
}
|
||||
|
||||
throw cmisObjectsUtils.createCmisException(("Runtime error. Message: " + e.toString()), e);
|
||||
throw ExceptionUtil.createCmisException(("Runtime error. Message: " + e.toString()), e);
|
||||
}
|
||||
|
||||
public void afterThrowing(java.lang.Exception e) throws CmisException
|
||||
@@ -76,7 +69,7 @@ public class DMServicePortThrowsAdvice implements ThrowsAdvice
|
||||
|
||||
if (!(e instanceof CmisException))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Some error occured during last service invokation. Message: " + e.toString()), e);
|
||||
throw ExceptionUtil.createCmisException(("Some error occured during last service invokation. Message: " + e.toString()), e);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -31,18 +31,12 @@ import javax.xml.ws.Holder;
|
||||
|
||||
import org.alfresco.cmis.CMISContentStreamAllowedEnum;
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.PropertyFilter;
|
||||
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.service.cmr.lock.LockService;
|
||||
import org.alfresco.service.cmr.lock.LockStatus;
|
||||
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionHistory;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
|
||||
/**
|
||||
* Port for versioning service.
|
||||
@@ -53,13 +47,6 @@ import org.alfresco.service.cmr.version.VersionType;
|
||||
@javax.jws.WebService(name = "VersioningServicePort", serviceName = "VersioningService", portName = "VersioningServicePort", targetNamespace = "http://docs.oasis-open.org/ns/cmis/ws/200908/", endpointInterface = "org.alfresco.repo.cmis.ws.VersioningServicePort")
|
||||
public class DMVersioningServicePort extends DMAbstractServicePort implements VersioningServicePort
|
||||
{
|
||||
private LockService lockService;
|
||||
|
||||
public void setLockService(LockService lockService)
|
||||
{
|
||||
this.lockService = lockService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses the effect of a check-out. Removes the private working copy of the checked-out document object, allowing other documents in the version series to be checked out
|
||||
* again.
|
||||
@@ -73,31 +60,14 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
public void cancelCheckOut(String repositoryId, String objectId, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
assertVersionableIsTrue(documentNodeRef);
|
||||
boolean checkedOut = propertiesUtil.getProperty(documentNodeRef, CMISDictionaryModel.PROP_IS_VERSION_SERIES_CHECKED_OUT, false);
|
||||
NodeRef workingCopyNodeRef = definitelyGetWorkingCopy(checkedOut, documentNodeRef);
|
||||
checkOutCheckInService.cancelCheckout(workingCopyNodeRef);
|
||||
}
|
||||
|
||||
private void assertVersionableIsTrue(NodeRef workingCopyNodeRef) throws CmisException
|
||||
{
|
||||
if (!getTypeDefinition(workingCopyNodeRef).isVersionable())
|
||||
try
|
||||
{
|
||||
// FIXME: uncomment this when CMIS dictionary model will be corrected
|
||||
// throw cmisObjectsUtils.createCmisException("Document that was specified is not versionable", EnumServiceException.CONSTRAINT);
|
||||
cmisService.cancelCheckOut(objectId);
|
||||
}
|
||||
}
|
||||
|
||||
private CMISTypeDefinition getTypeDefinition(NodeRef nodeRef) throws CmisException
|
||||
{
|
||||
String typeId = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, null);
|
||||
CMISTypeDefinition typeDefinition = (null != typeId) ? (cmisDictionaryService.findType(typeId)) : (null);
|
||||
if (null == typeDefinition)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Object type property is invalid"), EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
return typeDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,46 +87,41 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
List<String> policies, CmisAccessControlListType addACEs, CmisAccessControlListType removeACEs, Holder<CmisExtensionType> extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef workingCopyNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId.value, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
assertVersionableIsTrue(workingCopyNodeRef);
|
||||
assertLatestVersion(workingCopyNodeRef, true);
|
||||
|
||||
String versionSeriesId = propertiesUtil.getProperty(workingCopyNodeRef, CMISDictionaryModel.PROP_VERSION_SERIES_ID, null);
|
||||
CMISTypeDefinition seriesObjectTypeDefinition = getTypeDefinition((NodeRef) cmisObjectsUtils.getIdentifierInstance(versionSeriesId, AlfrescoObjectType.DOCUMENT_OBJECT));
|
||||
|
||||
if ((null != contentStream) && (CMISContentStreamAllowedEnum.NOT_ALLOWED == seriesObjectTypeDefinition.getContentStreamAllowed()))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Content stream is not allowed", EnumServiceException.STREAM_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
if (contentStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ContentWriter writer = fileFolderService.getWriter(workingCopyNodeRef);
|
||||
writer.setMimetype(contentStream.getMimeType());
|
||||
writer.putContent(contentStream.getStream().getInputStream());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Exception while updating content stream", EnumServiceException.UPDATE_CONFLICT, e);
|
||||
}
|
||||
}
|
||||
|
||||
NodeRef nodeRef;
|
||||
try
|
||||
{
|
||||
nodeRef = checkOutCheckInService.checkin(workingCopyNodeRef, createVersionProperties(checkinComment, ((null == major) || major) ? (VersionType.MAJOR)
|
||||
: (VersionType.MINOR)));
|
||||
propertiesUtil.setProperties(nodeRef, properties, null);
|
||||
NodeRef workingCopyNodeRef = cmisService.getObject(objectId.value, NodeRef.class, true, true, true);
|
||||
CMISTypeDefinition seriesObjectTypeDefinition = cmisService.getTypeDefinition(workingCopyNodeRef);
|
||||
|
||||
if ((null != contentStream) && (CMISContentStreamAllowedEnum.NOT_ALLOWED == seriesObjectTypeDefinition.getContentStreamAllowed()))
|
||||
{
|
||||
throw ExceptionUtil.createCmisException("Content stream is not allowed", EnumServiceException.STREAM_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
if (contentStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ContentWriter writer = fileFolderService.getWriter(workingCopyNodeRef);
|
||||
writer.setMimetype(contentStream.getMimeType());
|
||||
writer.putContent(contentStream.getStream().getInputStream());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException("Exception while updating content stream", EnumServiceException.RUNTIME, e);
|
||||
}
|
||||
}
|
||||
|
||||
propertiesUtil.setProperties(workingCopyNodeRef, properties, null);
|
||||
NodeRef nodeRef = cmisService.checkIn(objectId.value, checkinComment, major == null || major);
|
||||
|
||||
// TODO: applyPolicies
|
||||
applyAclCarefully(nodeRef, addACEs, removeACEs, EnumACLPropagation.PROPAGATE);
|
||||
objectId.value = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_OBJECT_ID, objectId.value);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Unable to check in Private Working Copy object that was specified", EnumServiceException.STORAGE, e);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
// TODO: applyPolicies
|
||||
applyAclCarefully(nodeRef, addACEs, removeACEs, EnumACLPropagation.PROPAGATE);
|
||||
objectId.value = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_OBJECT_ID, objectId.value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,48 +137,18 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
public void checkOut(String repositoryId, Holder<String> objectId, Holder<CmisExtensionType> extension, Holder<Boolean> contentCopied) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId.value, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
assertVersionableIsTrue(documentNodeRef);
|
||||
assertLatestVersion(documentNodeRef, false);
|
||||
|
||||
LockStatus lockStatus = lockService.getLockStatus(documentNodeRef);
|
||||
if (lockStatus.equals(LockStatus.LOCKED) || lockStatus.equals(LockStatus.LOCK_OWNER) || nodeService.hasAspect(documentNodeRef, ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Object is locked or already checked out", EnumServiceException.UPDATE_CONFLICT);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef pwcNodeRef = checkoutNode(documentNodeRef);
|
||||
NodeRef pwcNodeRef = cmisService.checkOut(objectId.value);
|
||||
objectId.value = propertiesUtil.getProperty(pwcNodeRef, CMISDictionaryModel.PROP_OBJECT_ID, objectId.value);
|
||||
contentCopied.value = null != fileFolderService.getReader(pwcNodeRef);
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Unable to execute Check Out services. Cause message: " + e.toString()), EnumServiceException.STORAGE);
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all document versions in the specified version series.
|
||||
*
|
||||
* @param repositoryId repository Id
|
||||
* @param versionSeriesId version series Id
|
||||
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME)
|
||||
*/
|
||||
public void deleteAllVersions(String repositoryId, String versionSeriesId) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(versionSeriesId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef workingCopyRef = (cmisObjectsUtils.isWorkingCopy(documentNodeRef)) ? (documentNodeRef) : (checkOutCheckInService.getWorkingCopy(documentNodeRef));
|
||||
if ((null != workingCopyRef) && cmisObjectsUtils.isWorkingCopy(workingCopyRef))
|
||||
{
|
||||
documentNodeRef = checkOutCheckInService.cancelCheckout(workingCopyRef);
|
||||
}
|
||||
|
||||
versionService.deleteVersionHistory(documentNodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of all document versions for the specified version series.
|
||||
*
|
||||
@@ -225,38 +160,23 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
documentNodeRef = cmisObjectsUtils.getLatestNode(documentNodeRef, false);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
List<CmisObjectType> objects = new LinkedList<CmisObjectType>();
|
||||
includeAllowableActions = (null == includeAllowableActions) ? (false) : (includeAllowableActions);
|
||||
|
||||
if (includeAllowableActions == null)
|
||||
{
|
||||
includeAllowableActions = false;
|
||||
}
|
||||
try
|
||||
{
|
||||
NodeRef workingCopyNodeReference = cmisObjectsUtils.isWorkingCopy(documentNodeRef) ? documentNodeRef : checkOutCheckInService.getWorkingCopy(documentNodeRef);
|
||||
if (null != workingCopyNodeReference)
|
||||
for (NodeRef nodeRef : cmisService.getAllVersions(objectId))
|
||||
{
|
||||
objects.add(createCmisObject(workingCopyNodeReference, propertyFilter, includeAllowableActions, null));
|
||||
objects.add(createCmisObject(nodeRef, propertyFilter, includeAllowableActions, null));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
if (!(e instanceof AccessDeniedException))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(e.toString(), EnumServiceException.RUNTIME);
|
||||
}
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
|
||||
VersionHistory versionHistory = versionService.getVersionHistory(documentNodeRef);
|
||||
if (null != versionHistory)
|
||||
{
|
||||
for (Version version = versionService.getCurrentVersion(documentNodeRef); null != version; version = versionHistory.getPredecessor(version))
|
||||
{
|
||||
objects.add(createCmisObject(version.getFrozenStateNodeRef(), propertyFilter, includeAllowableActions, null));
|
||||
}
|
||||
}
|
||||
// TODO: includeRelationships
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
@@ -271,43 +191,17 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
public CmisPropertiesType getPropertiesOfLatestVersion(String repositoryId, String objectId, Boolean major, String filter, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
NodeRef latestVersionNodeRef;
|
||||
try
|
||||
{
|
||||
latestVersionNodeRef = cmisService.getLatestVersion(objectId, major != null && major);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
major = (null == major) ? (false) : (major);
|
||||
NodeRef latestVersionNodeRef = getAndCheckLatestNodeRef(documentNodeRef, major);
|
||||
return propertiesUtil.getPropertiesType(latestVersionNodeRef.toString(), propertyFilter);
|
||||
}
|
||||
|
||||
private void assertLatestVersion(NodeRef nodeRef, boolean mustBePwc) throws CmisException
|
||||
{
|
||||
if (mustBePwc)
|
||||
{
|
||||
boolean checkedOut = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_IS_VERSION_SERIES_CHECKED_OUT, false);
|
||||
definitelyGetWorkingCopy(checkedOut, nodeRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
Boolean latestVersion = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_IS_LATEST_VERSION, false);
|
||||
if (!latestVersion && !cmisObjectsUtils.isWorkingCopy(nodeRef))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Operation can be executed only on the latest document version", EnumServiceException.VERSIONING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private NodeRef definitelyGetWorkingCopy(boolean checkedOut, NodeRef nodeRef) throws CmisException
|
||||
{
|
||||
NodeRef workingCopy = null;
|
||||
String workingCopyId = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_VERSION_SERIES_CHECKED_OUT_ID, null);
|
||||
if (checkedOut && (null != workingCopyId) && !"".equals(workingCopyId))
|
||||
{
|
||||
workingCopy = cmisObjectsUtils.getIdentifierInstance(workingCopyId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
}
|
||||
if ((null == workingCopy) || !cmisObjectsUtils.isWorkingCopy(workingCopy))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Object isn't checked out", EnumServiceException.UPDATE_CONFLICT);
|
||||
}
|
||||
return workingCopy;
|
||||
return propertiesUtil.getProperties(latestVersionNodeRef, propertyFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -318,29 +212,23 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
|
||||
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePolicyIds, Boolean includeACL, CmisExtensionType extension) throws CmisException
|
||||
{
|
||||
checkRepositoryId(repositoryId);
|
||||
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT);
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
includeAllowableActions = (null == includeAllowableActions) ? (false) : (includeAllowableActions);
|
||||
major = (null == major) ? (false) : (major);
|
||||
NodeRef latestVersionNodeRef = getAndCheckLatestNodeRef(documentNodeRef, major);
|
||||
// TODO: includeRelationships
|
||||
// TODO: includePolicyIds
|
||||
CmisObjectType result = createCmisObject(latestVersionNodeRef.toString(), propertyFilter, includeAllowableActions, renditionFilter);
|
||||
if (includeACL)
|
||||
try
|
||||
{
|
||||
appendWithAce(documentNodeRef, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
NodeRef latestVersionNodeRef = cmisService.getLatestVersion(objectId, major != null && major);
|
||||
// TODO: includeRelationships
|
||||
// TODO: includePolicyIds
|
||||
PropertyFilter propertyFilter = createPropertyFilter(filter);
|
||||
CmisObjectType result = createCmisObject(latestVersionNodeRef, propertyFilter, includeAllowableActions, renditionFilter);
|
||||
if (includeACL)
|
||||
{
|
||||
appendWithAce(cmisService.getVersionSeries(objectId, NodeRef.class, false), result);
|
||||
}
|
||||
|
||||
private NodeRef getAndCheckLatestNodeRef(NodeRef documentNodeRef, Boolean major) throws CmisException
|
||||
{
|
||||
NodeRef latestVersionNodeRef = cmisObjectsUtils.getLatestNode(documentNodeRef, major);
|
||||
Boolean majorVersionProperty = propertiesUtil.getProperty(latestVersionNodeRef, CMISDictionaryModel.PROP_IS_MAJOR_VERSION, false);
|
||||
if (major && !majorVersionProperty)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("Object that was specified has no latest major version", EnumServiceException.OBJECT_NOT_FOUND);
|
||||
return result;
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e);
|
||||
}
|
||||
return latestVersionNodeRef;
|
||||
}
|
||||
}
|
||||
|
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.mapping.CMISMapping;
|
||||
import org.alfresco.model.ContentModel;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public enum AlfrescoObjectType
|
||||
{
|
||||
DOCUMENT_OBJECT(ContentModel.TYPE_CONTENT.toString()),
|
||||
FOLDER_OBJECT(ContentModel.TYPE_FOLDER.toString()),
|
||||
DOCUMENT_OR_FOLDER_OBJECT("DOCUMENT_OR_FOLDER"),
|
||||
RELATIONSHIP_OBJECT(CMISMapping.RELATIONSHIP_QNAME.toString()),
|
||||
ANY_OBJECT("ANY");
|
||||
|
||||
String value;
|
||||
|
||||
final static Map<String, AlfrescoObjectType> VALUES;
|
||||
static
|
||||
{
|
||||
VALUES = new HashMap<String, AlfrescoObjectType>();
|
||||
VALUES.put(DOCUMENT_OBJECT.getValue(), DOCUMENT_OBJECT);
|
||||
VALUES.put(FOLDER_OBJECT.getValue(), FOLDER_OBJECT);
|
||||
}
|
||||
|
||||
AlfrescoObjectType(String value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static AlfrescoObjectType fromValue(String valueName)
|
||||
{
|
||||
AlfrescoObjectType result = VALUES.get(valueName);
|
||||
if (result == null)
|
||||
{
|
||||
result = ANY_OBJECT;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@@ -1,364 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.ws.EnumUnfileObject;
|
||||
import org.alfresco.repo.model.filefolder.FileInfoImpl;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* This class enumerates Documents and Folders hierarchy that begins from specified folder. Iterator returns Document or Empty Folder Objects those may be removed or deleted from
|
||||
* repository according to {@link EnumUnfileObject} <b>unfileObject</b> and {@link Boolean} <b>continueOnFailure</b> parameters. After hierarchy enumerating completion iterator may
|
||||
* introduce Object Id(s) {@link List} those were not deleted due to {@link Exception}(s)
|
||||
*
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class CmisObjectIterator implements Iterator<FileInfo>
|
||||
{
|
||||
private EnumUnfileObject unfillingStrategy;
|
||||
private boolean continueOnFailure;
|
||||
|
||||
private NodeService nodeService;
|
||||
private FileFolderService fileFolderService;
|
||||
private VersionService versionService;
|
||||
private CheckOutCheckInService checkOutCheckInService;
|
||||
private CmisObjectsUtils objectsUtils;
|
||||
|
||||
private Map<FileInfo, List<FileInfo>> hierarchy = new HashMap<FileInfo, List<FileInfo>>();
|
||||
private LinkedList<FileInfo> objects = new LinkedList<FileInfo>();
|
||||
private List<String> failToDelete = new LinkedList<String>();
|
||||
|
||||
private FileInfo next;
|
||||
private boolean lastDeleted;
|
||||
private boolean nextFound;
|
||||
private boolean deleteAllVersions;
|
||||
|
||||
/**
|
||||
* Mandatory constructor
|
||||
*
|
||||
* @param rootObject - {@link NodeRef} instance that represents Root folder for hierarchy
|
||||
* @param unfillingStrategy - {@link EnumUnfileObject} value that determines File-able Objects deletion or removing strategy
|
||||
* @param continueOnFailure - {@link Boolean} value that determines whether it is necessary continue deletion after some {@link Exception} occurred
|
||||
* @param nodeService - A {@link NodeService} implementation instance for manipulating with Object Properties
|
||||
* @param fileFolderService - A {@link FileFolderService} implementation instance for manipulating with Objects
|
||||
* @param objectsUtils - {@link CmisObjectsUtils} service instance for simplifying manipulations with Objects and Object Properties
|
||||
*/
|
||||
public CmisObjectIterator(NodeRef rootObject, EnumUnfileObject unfillingStrategy, boolean continueOnFailure, boolean deleteAllVersions, NodeService nodeService,
|
||||
FileFolderService fileFolderService, VersionService versionService, CheckOutCheckInService checkOutCheckInService, CmisObjectsUtils objectsUtils)
|
||||
{
|
||||
this.unfillingStrategy = unfillingStrategy;
|
||||
this.deleteAllVersions = deleteAllVersions;
|
||||
this.continueOnFailure = continueOnFailure;
|
||||
this.nodeService = nodeService;
|
||||
this.fileFolderService = fileFolderService;
|
||||
this.versionService = versionService;
|
||||
this.checkOutCheckInService = checkOutCheckInService;
|
||||
this.objectsUtils = objectsUtils;
|
||||
objects.add(new ParentedFileInfo(fileFolderService.getFileInfo(rootObject), null));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method performs searching for next Object (see {@link CmisObjectIterator})
|
||||
*/
|
||||
public boolean hasNext()
|
||||
{
|
||||
if (nextFound)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (objects.isEmpty() || (!failToDelete.isEmpty() && !continueOnFailure))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (next = objects.removeFirst(); processFolder() && !objects.isEmpty(); next = objects.removeFirst())
|
||||
{
|
||||
}
|
||||
nextFound = (null != next) && (!next.isFolder() || (null == receiveChildren(next.getNodeRef())));
|
||||
return nextFound;
|
||||
}
|
||||
|
||||
private boolean processFolder()
|
||||
{
|
||||
if (next.isFolder())
|
||||
{
|
||||
List<ChildAssociationRef> children = receiveChildren(next.getNodeRef());
|
||||
if (null != children)
|
||||
{
|
||||
objects.addFirst(next);
|
||||
for (ChildAssociationRef child : children)
|
||||
{
|
||||
FileInfo info = fileFolderService.getFileInfo(child.getChildRef());
|
||||
ParentedFileInfo childInfo = new ParentedFileInfo(info, next);
|
||||
objects.addFirst(childInfo);
|
||||
addChildToParent(next, childInfo);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addChildToParent(FileInfo parent, FileInfo child)
|
||||
{
|
||||
if (null != parent)
|
||||
{
|
||||
List<FileInfo> children;
|
||||
if (hierarchy.containsKey(parent))
|
||||
{
|
||||
children = hierarchy.get(parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
children = new LinkedList<FileInfo>();
|
||||
hierarchy.put(parent, children);
|
||||
}
|
||||
children.add(child);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ChildAssociationRef> receiveChildren(NodeRef folderRef)
|
||||
{
|
||||
if (null != folderRef)
|
||||
{
|
||||
List<ChildAssociationRef> result = nodeService.getChildAssocs(folderRef);
|
||||
if ((null != result) && !result.isEmpty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns currently enumerated Object and changes flag to enumerate next Object
|
||||
*
|
||||
* @see CmisObjectIterator
|
||||
* @see CmisObjectIterator#hasNext()
|
||||
* @see CmisObjectIterator#remove()
|
||||
*/
|
||||
public FileInfo next()
|
||||
{
|
||||
nextFound = false;
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method removes currently enumerated Object (see {@link CmisObjectIterator}). If Object deletion or removing fails due to {@link Exception} then according to
|
||||
* <b>continueOnFailure</b> parameter current Object Id and (if <b>continueOnFailure</b>="<b>true</b>") current Object Parent(s)' Id(s) will be stored in <b>failedToDelete</b>
|
||||
* {@link List}. Not deleted Object and its Parent(s) never will be enumerated again
|
||||
*
|
||||
* @see CmisObjectIterator
|
||||
* @see CmisObjectIterator#hasNext()
|
||||
* @see CmisObjectIterator#next()
|
||||
*/
|
||||
public void remove()
|
||||
{
|
||||
lastDeleted = false;
|
||||
NodeRef parentRef = null;
|
||||
ParentedFileInfo info = null;
|
||||
if (null != next)
|
||||
{
|
||||
info = (ParentedFileInfo) next;
|
||||
EnumUnfileObject howToDelete = null;
|
||||
parentRef = (null != info.getExactParent()) ? (info.getExactParent().getNodeRef()) : (null);
|
||||
if ((null != parentRef) && ((EnumUnfileObject.DELETESINGLEFILED == unfillingStrategy) || !objectsUtils.isPrimaryObjectParent(parentRef, info.getNodeRef())))
|
||||
{
|
||||
howToDelete = EnumUnfileObject.DELETESINGLEFILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
howToDelete = EnumUnfileObject.DELETE;
|
||||
}
|
||||
if (EnumUnfileObject.DELETESINGLEFILED == howToDelete)
|
||||
{
|
||||
lastDeleted = objectsUtils.removeObject(info.getNodeRef(), parentRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (deleteAllVersions)
|
||||
{
|
||||
NodeRef workingCopyRef = (objectsUtils.isWorkingCopy(info.getNodeRef())) ? (info.getNodeRef()) : (checkOutCheckInService.getWorkingCopy(info.getNodeRef()));
|
||||
if (null == workingCopyRef)
|
||||
{
|
||||
versionService.deleteVersionHistory(info.getNodeRef());
|
||||
}
|
||||
}
|
||||
lastDeleted = (objectsUtils.deleteObject(info.getNodeRef()));
|
||||
}
|
||||
}
|
||||
if (!lastDeleted && (null != info))
|
||||
{
|
||||
failToDelete.add(generateId(info));
|
||||
if ((null == info.getExactParent()) && info.isFolder())
|
||||
{
|
||||
removeFolderFromCollections(info);
|
||||
}
|
||||
if (continueOnFailure)
|
||||
{
|
||||
for (; null != info.getExactParent(); info = (ParentedFileInfo) info.getExactParent())
|
||||
{
|
||||
failToDelete.add(generateId(info.getExactParent()));
|
||||
removeFolderFromCollections(info.getExactParent());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeFolderFromCollections(FileInfo object)
|
||||
{
|
||||
if (hierarchy.containsKey(object))
|
||||
{
|
||||
hierarchy.remove(object);
|
||||
objects.remove(object);
|
||||
}
|
||||
}
|
||||
|
||||
private String generateId(FileInfo object)
|
||||
{
|
||||
StringBuilder generator = new StringBuilder(object.getNodeRef().toString());
|
||||
Map<QName, Serializable> properties = object.getProperties();
|
||||
String versionLabel = (null != properties) ? ((String) properties.get(ContentModel.PROP_VERSION_LABEL)) : (null);
|
||||
if (null != versionLabel)
|
||||
{
|
||||
generator.append(CmisObjectsUtils.NODE_REFERENCE_ID_DELIMITER).append(versionLabel);
|
||||
}
|
||||
return generator.toString();
|
||||
}
|
||||
|
||||
public boolean wasLastRemoved()
|
||||
{
|
||||
return lastDeleted;
|
||||
}
|
||||
|
||||
public List<String> getFailToDelete()
|
||||
{
|
||||
return failToDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is {@link org.alfresco.jlan.server.filesys.FileInfo} implementation that uses {@link FileInfoImpl} instances to delegate core functionality. The main target of
|
||||
* this class is extended standard {@link FileInfo} Objects with Parent Object
|
||||
*
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
private class ParentedFileInfo implements FileInfo, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -3024276223816623074L;
|
||||
|
||||
private FileInfo delegator;
|
||||
private FileInfo exactParent;
|
||||
|
||||
public ParentedFileInfo(FileInfo delegator, FileInfo exactParent)
|
||||
{
|
||||
this.delegator = delegator;
|
||||
this.exactParent = exactParent;
|
||||
}
|
||||
|
||||
public ContentData getContentData()
|
||||
{
|
||||
return delegator.getContentData();
|
||||
}
|
||||
|
||||
public Date getCreatedDate()
|
||||
{
|
||||
return delegator.getCreatedDate();
|
||||
}
|
||||
|
||||
public NodeRef getLinkNodeRef()
|
||||
{
|
||||
return delegator.getLinkNodeRef();
|
||||
}
|
||||
|
||||
public Date getModifiedDate()
|
||||
{
|
||||
return delegator.getModifiedDate();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return delegator.getName();
|
||||
}
|
||||
|
||||
public NodeRef getNodeRef()
|
||||
{
|
||||
return delegator.getNodeRef();
|
||||
}
|
||||
|
||||
public Map<QName, Serializable> getProperties()
|
||||
{
|
||||
return delegator.getProperties();
|
||||
}
|
||||
|
||||
public boolean isFolder()
|
||||
{
|
||||
return delegator.isFolder();
|
||||
}
|
||||
|
||||
public boolean isLink()
|
||||
{
|
||||
return delegator.isLink();
|
||||
}
|
||||
|
||||
public FileInfo getExactParent()
|
||||
{
|
||||
return exactParent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
return delegator.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return delegator.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return delegator.toString();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,566 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISQueryException;
|
||||
import org.alfresco.cmis.CMISScope;
|
||||
import org.alfresco.cmis.CMISTypeDefinition;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.ws.CmisException;
|
||||
import org.alfresco.repo.cmis.ws.CmisFaultType;
|
||||
import org.alfresco.repo.cmis.ws.EnumBaseObjectTypeIds;
|
||||
import org.alfresco.repo.cmis.ws.EnumRelationshipDirection;
|
||||
import org.alfresco.repo.cmis.ws.EnumServiceException;
|
||||
import org.alfresco.repo.cmis.ws.EnumUnfileObject;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.lock.LockService;
|
||||
import org.alfresco.service.cmr.lock.LockStatus;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.repository.AssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionHistory;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.QNamePattern;
|
||||
import org.springframework.extensions.surf.util.Pair;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public class CmisObjectsUtils
|
||||
{
|
||||
public static final String NODE_REFERENCE_ID_DELIMITER = ";";
|
||||
|
||||
private static final Pattern VERSION_LABEL_MATCHING_COMPILED_PATTERN = Pattern.compile("([\\p{Graph}])+([\\p{Digit}]*)\\.([\\p{Digit}]*)$");
|
||||
|
||||
private static final String INVALID_OBJECT_IDENTIFIER_MESSAGE = "Invalid Object Identifier was specified: Identifier is incorrect or Object with the specified Identifier does not exist";
|
||||
|
||||
private static final List<QName> DOCUMENT_AND_FOLDER_TYPES;
|
||||
static
|
||||
{
|
||||
DOCUMENT_AND_FOLDER_TYPES = new LinkedList<QName>();
|
||||
DOCUMENT_AND_FOLDER_TYPES.add(ContentModel.TYPE_CONTENT);
|
||||
DOCUMENT_AND_FOLDER_TYPES.add(ContentModel.TYPE_FOLDER);
|
||||
}
|
||||
|
||||
private static final Map<String, EnumServiceException> CLASS_TO_ENUM_EXCEPTION_MAPPING;
|
||||
static
|
||||
{
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING = new HashMap<String, EnumServiceException>();
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(AccessDeniedException.class.getName(), EnumServiceException.PERMISSION_DENIED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(java.lang.RuntimeException.class.getName(), EnumServiceException.RUNTIME);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(UnsupportedOperationException.class.getName(), EnumServiceException.NOT_SUPPORTED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(InvalidNodeRefException.class.getName(), EnumServiceException.INVALID_ARGUMENT);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(ContentIOException.class.getName(), EnumServiceException.NOT_SUPPORTED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(CMISQueryException.class.getName(), EnumServiceException.INVALID_ARGUMENT);
|
||||
// TODO: insert CLASS_TO_ENUM_EXCEPTION_MAPPING.put(<Concreate_Exception_Type>.class.getName(), EnumServiceException.<Appropriate_Enum_value>);
|
||||
}
|
||||
|
||||
private CheckOutCheckInService checkOutCheckInService;
|
||||
private CMISDictionaryService cmisDictionaryService;
|
||||
private FileFolderService fileFolderService;
|
||||
private AuthorityService authorityService;
|
||||
private VersionService versionService;
|
||||
private NodeService nodeService;
|
||||
private LockService lockService;
|
||||
|
||||
private Throwable lastException;
|
||||
|
||||
public void setCmisDictionaryService(CMISDictionaryService cmisDictionaryService)
|
||||
{
|
||||
this.cmisDictionaryService = cmisDictionaryService;
|
||||
}
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setFileFolderService(FileFolderService fileFolderService)
|
||||
{
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
public void setLockService(LockService lockService)
|
||||
{
|
||||
this.lockService = lockService;
|
||||
}
|
||||
|
||||
public void setCheckOutCheckInService(CheckOutCheckInService checkOutCheckInService)
|
||||
{
|
||||
this.checkOutCheckInService = checkOutCheckInService;
|
||||
}
|
||||
|
||||
public void setAuthorityService(AuthorityService authorityService)
|
||||
{
|
||||
this.authorityService = authorityService;
|
||||
}
|
||||
|
||||
public void setVersionService(VersionService versionService)
|
||||
{
|
||||
this.versionService = versionService;
|
||||
}
|
||||
|
||||
public CmisException createCmisException(String message, EnumServiceException exceptionType)
|
||||
{
|
||||
return createCmisException(message, exceptionType, null, 0);
|
||||
}
|
||||
|
||||
public CmisException createCmisException(String message, Throwable cause)
|
||||
{
|
||||
EnumServiceException exceptionType = null;
|
||||
|
||||
if (CLASS_TO_ENUM_EXCEPTION_MAPPING.containsKey(cause.getClass().getName()))
|
||||
{
|
||||
exceptionType = CLASS_TO_ENUM_EXCEPTION_MAPPING.get(cause.getClass().getName());
|
||||
}
|
||||
|
||||
exceptionType = (exceptionType == null) ? (EnumServiceException.RUNTIME) : (exceptionType);
|
||||
|
||||
return createCmisException(message, exceptionType, cause, 0);
|
||||
}
|
||||
|
||||
public CmisException createCmisException(String message, EnumServiceException exceptionType, Throwable cause)
|
||||
{
|
||||
return createCmisException(message, exceptionType, cause, 0);
|
||||
}
|
||||
|
||||
public CmisException createCmisException(String message, EnumServiceException exceptionType, Throwable cause, int errorCode)
|
||||
{
|
||||
CmisFaultType fault = new CmisFaultType();
|
||||
fault.setMessage(message);
|
||||
fault.setType(exceptionType);
|
||||
fault.setCode(BigInteger.valueOf(errorCode));
|
||||
|
||||
return new CmisException(message, fault, cause);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <IdentifierType> IdentifierType getIdentifierInstance(String identifier, AlfrescoObjectType expectedType) throws CmisException
|
||||
{
|
||||
if (!(identifier instanceof String))
|
||||
{
|
||||
throw createCmisException("Invalid Object Identifier was specified", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
IdentifierType result;
|
||||
AlfrescoObjectType actualObjectType;
|
||||
|
||||
if (isRelationship(identifier))
|
||||
{
|
||||
result = (IdentifierType) safeGetAssociationRef(identifier);
|
||||
actualObjectType = AlfrescoObjectType.RELATIONSHIP_OBJECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef nodeReference = safeGetNodeRef(identifier);
|
||||
result = (IdentifierType) nodeReference;
|
||||
actualObjectType = determineActualObjectType(expectedType, this.nodeService.getType(nodeReference));
|
||||
}
|
||||
|
||||
if ((AlfrescoObjectType.ANY_OBJECT == expectedType) || (actualObjectType == expectedType))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
throw createCmisException(("Unexpected object type of the specified Object with \"" + identifier + "\" identifier"), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
public List<String> deleteFolder(NodeRef folderNodeReference, boolean continueOnFailure, EnumUnfileObject unfillingStrategy, boolean deleteAllVersions) throws CmisException
|
||||
{
|
||||
CmisObjectIterator iterator = new CmisObjectIterator(folderNodeReference, unfillingStrategy, continueOnFailure, deleteAllVersions, nodeService, fileFolderService,
|
||||
versionService, checkOutCheckInService, this);
|
||||
if (iterator.hasNext())
|
||||
{
|
||||
for (; iterator.hasNext(); iterator.next())
|
||||
{
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
return iterator.getFailToDelete();
|
||||
}
|
||||
|
||||
public boolean deleteObject(NodeRef objectNodeReference)
|
||||
{
|
||||
if (null == objectNodeReference)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (versionService.getVersionStoreReference().getIdentifier().equals(objectNodeReference.getStoreRef().getIdentifier()))
|
||||
{
|
||||
String versionLabel = (String) nodeService.getProperty(objectNodeReference, ContentModel.PROP_VERSION_LABEL);
|
||||
|
||||
if ((null != versionLabel) && !versionLabel.equals(""))
|
||||
{
|
||||
Version currentVersion = versionService.getCurrentVersion(objectNodeReference);
|
||||
|
||||
if ((null != currentVersion) && nodeService.exists(currentVersion.getVersionedNodeRef()))
|
||||
{
|
||||
versionService.deleteVersion(currentVersion.getVersionedNodeRef(), currentVersion);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return canLock(objectNodeReference) && performNodeDeletion(objectNodeReference);
|
||||
}
|
||||
|
||||
public boolean removeObject(NodeRef objectNodeReference, NodeRef folderNodeReference)
|
||||
{
|
||||
if (isChildOfThisFolder(objectNodeReference, folderNodeReference))
|
||||
{
|
||||
try
|
||||
{
|
||||
this.nodeService.removeChild(folderNodeReference, objectNodeReference);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
lastException = e;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean addObjectToFolder(NodeRef objectNodeRef, NodeRef parentFolderNodeRef)
|
||||
{
|
||||
try
|
||||
{
|
||||
QName name = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName((String) nodeService.getProperty(objectNodeRef,
|
||||
ContentModel.PROP_NAME)));
|
||||
nodeService.addChild(parentFolderNodeRef, objectNodeRef, ContentModel.ASSOC_CONTAINS, name);
|
||||
return true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
lastException = e;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFolder(NodeRef folderNodeRef)
|
||||
{
|
||||
if (folderNodeRef == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QName typeQName = nodeService.getType(folderNodeRef);
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForClass(typeQName, CMISScope.FOLDER);
|
||||
return typeDef != null;
|
||||
}
|
||||
|
||||
public boolean isDocument(NodeRef documentNodeRef)
|
||||
{
|
||||
if (documentNodeRef == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
QName typeQName = nodeService.getType(documentNodeRef);
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForClass(typeQName, CMISScope.DOCUMENT);
|
||||
return typeDef != null;
|
||||
}
|
||||
|
||||
public boolean isRelationship(String identifier)
|
||||
{
|
||||
try
|
||||
{
|
||||
new AssociationRef(identifier);
|
||||
return true;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPolicy(NodeRef policyNodeRef)
|
||||
{
|
||||
// TODO: Policy
|
||||
return false;
|
||||
}
|
||||
|
||||
public EnumBaseObjectTypeIds determineObjectType(String identifier)
|
||||
{
|
||||
if (isRelationship(identifier))
|
||||
{
|
||||
return EnumBaseObjectTypeIds.CMIS_RELATIONSHIP;
|
||||
}
|
||||
|
||||
NodeRef objectNodeReference = new NodeRef(identifier);
|
||||
if (isFolder(objectNodeReference))
|
||||
{
|
||||
return EnumBaseObjectTypeIds.CMIS_FOLDER;
|
||||
}
|
||||
|
||||
if (isDocument(objectNodeReference))
|
||||
{
|
||||
return EnumBaseObjectTypeIds.CMIS_DOCUMENT;
|
||||
}
|
||||
|
||||
return EnumBaseObjectTypeIds.CMIS_POLICY;
|
||||
}
|
||||
|
||||
public boolean isChildOfThisFolder(NodeRef objectNodeReference, NodeRef folderNodeReference)
|
||||
{
|
||||
NodeRef searchedObjectNodeReference = fileFolderService.searchSimple(folderNodeReference, (String) nodeService.getProperty(objectNodeReference, ContentModel.PROP_NAME));
|
||||
return (searchedObjectNodeReference != null) && searchedObjectNodeReference.equals(objectNodeReference);
|
||||
}
|
||||
|
||||
public boolean isPrimaryObjectParent(NodeRef folderNodeReference, NodeRef objectNodeReference)
|
||||
{
|
||||
NodeRef searchedParentObject = nodeService.getPrimaryParent(objectNodeReference).getParentRef();
|
||||
return (searchedParentObject != null) && searchedParentObject.equals(folderNodeReference);
|
||||
}
|
||||
|
||||
public boolean isWorkingCopy(NodeRef objectIdentifier)
|
||||
{
|
||||
return nodeService.hasAspect(objectIdentifier, ContentModel.ASPECT_WORKING_COPY);
|
||||
}
|
||||
|
||||
public List<AssociationRef> receiveAssociations(NodeRef objectNodeReference, QNamePattern qnameFilter, EnumRelationshipDirection direction)
|
||||
{
|
||||
List<AssociationRef> result = new LinkedList<AssociationRef>();
|
||||
|
||||
if ((direction == EnumRelationshipDirection.EITHER) || (direction == EnumRelationshipDirection.TARGET))
|
||||
{
|
||||
result.addAll(nodeService.getSourceAssocs(objectNodeReference, qnameFilter));
|
||||
}
|
||||
|
||||
if ((direction == EnumRelationshipDirection.EITHER) || (direction == EnumRelationshipDirection.SOURCE))
|
||||
{
|
||||
result.addAll(nodeService.getTargetAssocs(objectNodeReference, qnameFilter));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns latest minor or major version of document
|
||||
*
|
||||
* @param documentNodeRef document node reference
|
||||
* @param major need latest major version
|
||||
* @return latest version node reference
|
||||
*/
|
||||
public NodeRef getLatestNode(NodeRef documentNodeRef, boolean major)
|
||||
{
|
||||
NodeRef latestVersionNodeRef = documentNodeRef;
|
||||
VersionHistory versionHistory = versionService.getVersionHistory(documentNodeRef);
|
||||
if (null != versionHistory)
|
||||
{
|
||||
Collection<Version> allVersions = versionHistory.getAllVersions();
|
||||
Iterator<Version> versionsIterator = ((null != allVersions) && !allVersions.isEmpty()) ? (allVersions.iterator()) : (null);
|
||||
Version latestVersion = (null == versionsIterator) ? (null) : (versionsIterator.next());
|
||||
String currentVersionLabel = (null != latestVersion) ? (latestVersion.getVersionLabel()) : (null);
|
||||
if (major && (null != latestVersion))
|
||||
{
|
||||
for (; (VersionType.MAJOR != latestVersion.getVersionType()) && versionsIterator.hasNext(); latestVersion = versionsIterator.next())
|
||||
{
|
||||
}
|
||||
latestVersion = (VersionType.MAJOR != latestVersion.getVersionType()) ? (null) : (latestVersion);
|
||||
}
|
||||
if ((null != latestVersion) && (null != latestVersion.getVersionLabel()))
|
||||
{
|
||||
latestVersionNodeRef = (!latestVersion.getVersionLabel().equals(currentVersionLabel) || (null == latestVersion.getVersionedNodeRef()) || !nodeService
|
||||
.exists(latestVersion.getVersionedNodeRef())) ? (latestVersion.getFrozenStateNodeRef()) : (latestVersion.getVersionedNodeRef());
|
||||
}
|
||||
}
|
||||
|
||||
return latestVersionNodeRef;
|
||||
}
|
||||
|
||||
private boolean performNodeDeletion(NodeRef objectNodeReference)
|
||||
{
|
||||
if (nodeService.hasAspect(objectNodeReference, ContentModel.ASPECT_WORKING_COPY))
|
||||
{
|
||||
checkOutCheckInService.cancelCheckout(objectNodeReference);
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
List<AssociationRef> associations = receiveAssociations(objectNodeReference, new MatcheAllQNames(), EnumRelationshipDirection.EITHER);
|
||||
for (AssociationRef association : associations)
|
||||
{
|
||||
if ((null != association) && (null != association.getSourceRef()) && (null != association.getTargetRef()) && (null != association.getTypeQName()))
|
||||
{
|
||||
nodeService.removeAssociation(association.getSourceRef(), association.getTargetRef(), association.getTypeQName());
|
||||
}
|
||||
}
|
||||
|
||||
for (ChildAssociationRef parentAssociation : nodeService.getParentAssocs(objectNodeReference))
|
||||
{
|
||||
if (!parentAssociation.isPrimary())
|
||||
{
|
||||
nodeService.removeChildAssociation(parentAssociation);
|
||||
}
|
||||
}
|
||||
|
||||
nodeService.deleteNode(objectNodeReference);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
lastException = e;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean canLock(NodeRef objectNodeReference)
|
||||
{
|
||||
String currentUserName = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
return (this.lockService.getLockStatus(objectNodeReference, currentUserName) != LockStatus.LOCKED) || authorityService.isAdminAuthority(currentUserName);
|
||||
}
|
||||
|
||||
private AssociationRef safeGetAssociationRef(String identifier) throws CmisException
|
||||
{
|
||||
AssociationRef result = new AssociationRef(identifier);
|
||||
|
||||
if (!nodeService.exists(result.getSourceRef()) || !nodeService.exists(result.getTargetRef()))
|
||||
{
|
||||
throw createCmisException(INVALID_OBJECT_IDENTIFIER_MESSAGE, EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private NodeRef safeGetNodeRef(String nodeIdentifier) throws CmisException
|
||||
{
|
||||
Pair<String, String> nodeRefAndVersionLabel = (null != nodeIdentifier) ? (splitOnNodeRefAndVersionLabel(nodeIdentifier)) : (null);
|
||||
if ((null != nodeRefAndVersionLabel) && (null != nodeRefAndVersionLabel.getFirst()) && NodeRef.isNodeRef(nodeRefAndVersionLabel.getFirst()))
|
||||
{
|
||||
NodeRef result = new NodeRef(nodeRefAndVersionLabel.getFirst());
|
||||
if (nodeService.exists(result))
|
||||
{
|
||||
result = getNodeRefFromVersion(result, nodeRefAndVersionLabel.getSecond());
|
||||
|
||||
if ((null != result) && nodeService.exists(result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw createCmisException(INVALID_OBJECT_IDENTIFIER_MESSAGE, EnumServiceException.OBJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
private Pair<String, String> splitOnNodeRefAndVersionLabel(String nodeIdentifier)
|
||||
{
|
||||
String versionLabel = null;
|
||||
int versionDelimeterIndex = nodeIdentifier.lastIndexOf(NODE_REFERENCE_ID_DELIMITER);
|
||||
if (versionDelimeterIndex > 0)
|
||||
{
|
||||
versionLabel = nodeIdentifier.substring(versionDelimeterIndex + 1);
|
||||
if ((null != versionLabel) && !versionLabel.equals("") && VERSION_LABEL_MATCHING_COMPILED_PATTERN.matcher(versionLabel).matches())
|
||||
{
|
||||
nodeIdentifier = nodeIdentifier.substring(0, versionDelimeterIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
versionLabel = null;
|
||||
}
|
||||
}
|
||||
|
||||
return new Pair<String, String>(nodeIdentifier, versionLabel);
|
||||
}
|
||||
|
||||
private NodeRef getNodeRefFromVersion(NodeRef nodeRef, String versionLabel) throws CmisException
|
||||
{
|
||||
NodeRef result = nodeRef;
|
||||
|
||||
NodeRef latestNodeRef = ((null != versionLabel) && (null != nodeRef)) ? (getLatestNode(nodeRef, false)) : (null);
|
||||
if ((null != latestNodeRef) && nodeService.exists(latestNodeRef) && !versionLabel.equals(nodeService.getProperty(latestNodeRef, ContentModel.PROP_VERSION_LABEL)))
|
||||
{
|
||||
VersionHistory versionHistory = versionService.getVersionHistory(latestNodeRef);
|
||||
if (null != versionHistory)
|
||||
{
|
||||
Version version = versionHistory.getVersion(versionLabel);
|
||||
|
||||
if ((null == version) || (null == version.getFrozenStateNodeRef()))
|
||||
{
|
||||
throw createCmisException(("Specified object has no " + versionLabel + " version"), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
result = version.getFrozenStateNodeRef();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private AlfrescoObjectType determineActualObjectType(AlfrescoObjectType expectedType, QName objectType)
|
||||
{
|
||||
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForClass(objectType);
|
||||
if ((expectedType == AlfrescoObjectType.DOCUMENT_OBJECT || expectedType == AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT)
|
||||
&& typeDef.getTypeId().getScope() == CMISScope.DOCUMENT)
|
||||
{
|
||||
return expectedType;
|
||||
}
|
||||
if ((expectedType == AlfrescoObjectType.FOLDER_OBJECT || expectedType == AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT)
|
||||
&& typeDef.getTypeId().getScope() == CMISScope.FOLDER)
|
||||
{
|
||||
return expectedType;
|
||||
}
|
||||
return AlfrescoObjectType.ANY_OBJECT;
|
||||
}
|
||||
|
||||
private class MatcheAllQNames implements QNamePattern
|
||||
{
|
||||
public boolean isMatch(QName qname)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public Throwable getLastOperationException()
|
||||
{
|
||||
Throwable result = lastException;
|
||||
lastException = null;
|
||||
return result;
|
||||
}
|
||||
}
|
100
source/java/org/alfresco/repo/cmis/ws/utils/ExceptionUtil.java
Executable file
100
source/java/org/alfresco/repo/cmis/ws/utils/ExceptionUtil.java
Executable file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program 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 General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.cmis.CMISQueryException;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.repo.cmis.ws.CmisException;
|
||||
import org.alfresco.repo.cmis.ws.CmisFaultType;
|
||||
import org.alfresco.repo.cmis.ws.EnumServiceException;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
|
||||
/**
|
||||
* @author Dmitry Velichkevich
|
||||
*/
|
||||
public abstract class ExceptionUtil
|
||||
{
|
||||
private static final Map<String, EnumServiceException> CLASS_TO_ENUM_EXCEPTION_MAPPING;
|
||||
static
|
||||
{
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING = new HashMap<String, EnumServiceException>();
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(AccessDeniedException.class.getName(), EnumServiceException.PERMISSION_DENIED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(java.lang.RuntimeException.class.getName(), EnumServiceException.RUNTIME);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(UnsupportedOperationException.class.getName(), EnumServiceException.NOT_SUPPORTED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(InvalidNodeRefException.class.getName(), EnumServiceException.INVALID_ARGUMENT);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(ContentIOException.class.getName(), EnumServiceException.NOT_SUPPORTED);
|
||||
CLASS_TO_ENUM_EXCEPTION_MAPPING.put(CMISQueryException.class.getName(), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
public static CmisException createCmisException(String message, EnumServiceException exceptionType)
|
||||
{
|
||||
return createCmisException(message, exceptionType, null, 0);
|
||||
}
|
||||
|
||||
public static CmisException createCmisException(String message, Throwable cause)
|
||||
{
|
||||
EnumServiceException exceptionType = null;
|
||||
|
||||
if (cause instanceof CMISServiceException)
|
||||
{
|
||||
return createCmisException((CMISServiceException)cause);
|
||||
}
|
||||
|
||||
if (CLASS_TO_ENUM_EXCEPTION_MAPPING.containsKey(cause.getClass().getName()))
|
||||
{
|
||||
exceptionType = CLASS_TO_ENUM_EXCEPTION_MAPPING.get(cause.getClass().getName());
|
||||
}
|
||||
|
||||
exceptionType = (exceptionType == null) ? (EnumServiceException.RUNTIME) : (exceptionType);
|
||||
|
||||
return createCmisException(message, exceptionType, cause, 0);
|
||||
}
|
||||
|
||||
public static CmisException createCmisException(String message, EnumServiceException exceptionType, Throwable cause)
|
||||
{
|
||||
return createCmisException(message, exceptionType, cause, 0);
|
||||
}
|
||||
|
||||
public static CmisException createCmisException(CMISServiceException exception)
|
||||
{
|
||||
return createCmisException(exception.getMessage(), EnumServiceException.fromValue(exception.getFaultName()), exception, exception.getStatusCode());
|
||||
}
|
||||
|
||||
public static CmisException createCmisException(String message, EnumServiceException exceptionType, Throwable cause, int errorCode)
|
||||
{
|
||||
CmisFaultType fault = new CmisFaultType();
|
||||
fault.setMessage(message);
|
||||
fault.setType(exceptionType);
|
||||
fault.setCode(BigInteger.valueOf(errorCode));
|
||||
|
||||
return new CmisException(message, fault, cause);
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -15,11 +15,11 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.cmis.ws.utils;
|
||||
@@ -40,6 +40,7 @@ import javax.xml.datatype.XMLGregorianCalendar;
|
||||
import org.alfresco.cmis.CMISDataTypeEnum;
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISDictionaryService;
|
||||
import org.alfresco.cmis.CMISInvalidArgumentException;
|
||||
import org.alfresco.cmis.CMISPropertyDefinition;
|
||||
import org.alfresco.cmis.CMISScope;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
@@ -65,6 +66,7 @@ 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;
|
||||
|
||||
@@ -98,7 +100,6 @@ public class PropertyUtil
|
||||
private NamespaceService namespaceService;
|
||||
private CMISServices cmisService;
|
||||
private CMISDictionaryService cmisDictionaryService;
|
||||
private CmisObjectsUtils cmisObjectsUtils;
|
||||
|
||||
public PropertyUtil()
|
||||
{
|
||||
@@ -129,11 +130,6 @@ public class PropertyUtil
|
||||
this.cmisDictionaryService = cmisDictionaryService;
|
||||
}
|
||||
|
||||
public void setCmisObjectsUtils(CmisObjectsUtils cmisObjectsUtils)
|
||||
{
|
||||
this.cmisObjectsUtils = cmisObjectsUtils;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets property value by its name from Node Reference object
|
||||
*
|
||||
@@ -275,7 +271,7 @@ public class PropertyUtil
|
||||
|
||||
if ((PropertyMultiValueStateEnum.PROPERTY_NOT_MULTIVALUED == state) && (values.size() > 1))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException("\"" + propertyName + "\" property is not Multi Valued", EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException("\"" + propertyName + "\" property is not Multi Valued", EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
return PropertyMultiValueStateEnum.PROPERTY_MULTIVALUED == state;
|
||||
@@ -379,7 +375,7 @@ public class PropertyUtil
|
||||
|
||||
if ((null == cmisObjectType) && (null == nativeObjectType))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Can't find type definition for current object with \"" + typeId + "\" type Id"), EnumServiceException.INVALID_ARGUMENT);
|
||||
throw ExceptionUtil.createCmisException(("Can't find type definition for current object with \"" + typeId + "\" type Id"), EnumServiceException.INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
for (CmisProperty property : properties.getProperty())
|
||||
@@ -406,7 +402,7 @@ public class PropertyUtil
|
||||
}
|
||||
case PROPERTY_NOT_UPDATABLE:
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("\"" + propertyName + "\" property is not updatable by repository for specified Object id"),
|
||||
throw ExceptionUtil.createCmisException(("\"" + propertyName + "\" property is not updatable by repository for specified Object id"),
|
||||
EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
}
|
||||
@@ -479,7 +475,7 @@ public class PropertyUtil
|
||||
|
||||
if (propertyDefinition.isRequired() && (null == value))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException((propertyName + " property required"), EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException((propertyName + " property required"), EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
|
||||
switch (propertyDefinition.getDataType())
|
||||
@@ -514,7 +510,7 @@ public class PropertyUtil
|
||||
{
|
||||
if (value != null && (propertyDefinition.getMaximumLength() > 0) && (value.length() > propertyDefinition.getMaximumLength()))
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException((propertyName + " property value is too long"), EnumServiceException.CONSTRAINT);
|
||||
throw ExceptionUtil.createCmisException((propertyName + " property value is too long"), EnumServiceException.CONSTRAINT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,21 +521,32 @@ public class PropertyUtil
|
||||
* @param filter property filter
|
||||
* @return properties
|
||||
*/
|
||||
public CmisPropertiesType getPropertiesType(String identifier, PropertyFilter filter) throws CmisException
|
||||
public CmisPropertiesType getProperties(Object object, PropertyFilter filter) throws CmisException
|
||||
{
|
||||
Map<String, Serializable> properties;
|
||||
if (!identifier.contains("|"))
|
||||
try
|
||||
{
|
||||
properties = cmisService.getProperties(new NodeRef(identifier));
|
||||
}
|
||||
else
|
||||
{
|
||||
properties = createBaseRelationshipProperties(new AssociationRef(identifier));
|
||||
}
|
||||
Map<String, Serializable> properties;
|
||||
if (object instanceof NodeRef)
|
||||
{
|
||||
properties = cmisService.getProperties((NodeRef) object);
|
||||
}
|
||||
else if (object instanceof Version)
|
||||
{
|
||||
properties = cmisService.getProperties(((Version) object).getFrozenStateNodeRef());
|
||||
}
|
||||
else
|
||||
{
|
||||
properties = createBaseRelationshipProperties((AssociationRef) object);
|
||||
}
|
||||
|
||||
CmisPropertiesType result = new CmisPropertiesType();
|
||||
convertToCmisProperties(properties, filter, result);
|
||||
return result;
|
||||
CmisPropertiesType result = new CmisPropertiesType();
|
||||
convertToCmisProperties(properties, filter, result);
|
||||
return result;
|
||||
}
|
||||
catch (CMISInvalidArgumentException e)
|
||||
{
|
||||
throw ExceptionUtil.createCmisException(e.getMessage(), EnumServiceException.INVALID_ARGUMENT, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Serializable> createBaseRelationshipProperties(AssociationRef association)
|
||||
@@ -562,7 +569,7 @@ public class PropertyUtil
|
||||
|
||||
if (null == type)
|
||||
{
|
||||
throw cmisObjectsUtils.createCmisException(("Type with " + typeId + " typeId was not found"), EnumServiceException.RUNTIME);
|
||||
throw ExceptionUtil.createCmisException(("Type with " + typeId + " typeId was not found"), EnumServiceException.RUNTIME);
|
||||
}
|
||||
|
||||
for (String propertyName : properties.keySet())
|
||||
|
@@ -31,8 +31,8 @@ import java.util.Map;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
|
@@ -31,8 +31,8 @@ import java.util.Map;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
@@ -24,26 +24,22 @@
|
||||
*/
|
||||
package org.alfresco.repo.web.scripts.content;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.cmis.CMISDictionaryModel;
|
||||
import org.alfresco.cmis.CMISObjectReference;
|
||||
import org.alfresco.cmis.reference.ObjectPathReference;
|
||||
import org.alfresco.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.cmis.CMISServiceException;
|
||||
import org.alfresco.cmis.CMISServices;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.encoding.ContentCharsetFinder;
|
||||
import org.alfresco.repo.cmis.reference.ObjectPathReference;
|
||||
import org.alfresco.repo.cmis.reference.ReferenceFactory;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
@@ -74,7 +70,7 @@ public class ContentSet extends AbstractWebScript
|
||||
private ReferenceFactory referenceFactory;
|
||||
private DictionaryService dictionaryService;
|
||||
private NamespaceService namespaceService;
|
||||
private ContentService contentService;
|
||||
private CMISServices cmisService;
|
||||
private MimetypeService mimetypeService;
|
||||
|
||||
/**
|
||||
@@ -102,11 +98,11 @@ public class ContentSet extends AbstractWebScript
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contentService
|
||||
* @param cmisServices
|
||||
*/
|
||||
public void setContentService(ContentService contentService)
|
||||
public void setCmisService(CMISServices cmisService)
|
||||
{
|
||||
this.contentService = contentService;
|
||||
this.cmisService = cmisService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,22 +164,7 @@ public class ContentSet extends AbstractWebScript
|
||||
}
|
||||
|
||||
// ensure content can be overwritten
|
||||
// TODO: check parameter name
|
||||
String overwrite = req.getParameter("overwriteFlag");
|
||||
if (overwrite != null && overwrite.equalsIgnoreCase("false"))
|
||||
{
|
||||
ContentReader reader = contentService.getReader(nodeRef, propertyQName);
|
||||
if (reader != null)
|
||||
{
|
||||
// error code as per CMIS specification
|
||||
throw new WebScriptException(HttpServletResponse.SC_CONFLICT, "Content already exists.");
|
||||
}
|
||||
}
|
||||
|
||||
// setup content writer
|
||||
ContentReader reader = contentService.getReader(nodeRef, propertyQName);
|
||||
boolean isUpdate = (reader != null && reader.exists());
|
||||
ContentWriter writer = contentService.getWriter(nodeRef, propertyQName, true);
|
||||
|
||||
// establish mimetype
|
||||
String mimetype = req.getContentType();
|
||||
@@ -194,24 +175,19 @@ public class ContentSet extends AbstractWebScript
|
||||
mimetype = mimetypeService.guessMimetype(((ObjectPathReference)reference).getPath());
|
||||
}
|
||||
}
|
||||
if (mimetype != null)
|
||||
{
|
||||
writer.setMimetype(mimetype);
|
||||
}
|
||||
|
||||
// get the input stream from the request data
|
||||
InputStream is = req.getContent().getInputStream();
|
||||
is = is.markSupported() ? is : new BufferedInputStream(is);
|
||||
|
||||
// establish content encoding
|
||||
ContentCharsetFinder charsetFinder = mimetypeService.getContentCharsetFinder();
|
||||
Charset encoding = charsetFinder.getCharset(is, mimetype);
|
||||
writer.setEncoding(encoding.name());
|
||||
|
||||
// write the new data
|
||||
writer.putContent(is);
|
||||
|
||||
// set status
|
||||
res.setStatus(isUpdate ? Status.STATUS_OK : Status.STATUS_CREATED);
|
||||
try
|
||||
{
|
||||
boolean isUpdate = cmisService.setContentStream((String) cmisService.getProperty(nodeRef,
|
||||
CMISDictionaryModel.PROP_OBJECT_ID), propertyQName, overwrite == null || overwrite.equals("true"),
|
||||
req.getContent().getInputStream(), mimetype);
|
||||
|
||||
// set status
|
||||
res.setStatus(isUpdate ? Status.STATUS_OK : Status.STATUS_CREATED);
|
||||
}
|
||||
catch (CMISServiceException e)
|
||||
{
|
||||
throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user