From df089be8c4155b33a28a83487d5a8852473e0177 Mon Sep 17 00:00:00 2001 From: git -v Date: Fri, 18 Dec 2015 17:38:47 +0900 Subject: [PATCH 01/20] Modify : update and create develop script --- .gitignore | 1 + .../webapp/WEB-INF/classes/log4j.tomcat.xml | 29 ++++++++ setup/development/7za.exe | Bin 0 -> 643072 bytes setup/development/build.bat | 67 ++++++++++++++++++ setup/development/start.bat | 28 ++++---- 5 files changed, 111 insertions(+), 14 deletions(-) create mode 100644 core/src/main/webapp/WEB-INF/classes/log4j.tomcat.xml create mode 100644 setup/development/7za.exe create mode 100644 setup/development/build.bat diff --git a/.gitignore b/.gitignore index 1607740a..176a5b10 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ jetty.log .settings !.gitkeep setup/installer/*/log +target diff --git a/core/src/main/webapp/WEB-INF/classes/log4j.tomcat.xml b/core/src/main/webapp/WEB-INF/classes/log4j.tomcat.xml new file mode 100644 index 00000000..9486cb45 --- /dev/null +++ b/core/src/main/webapp/WEB-INF/classes/log4j.tomcat.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/setup/development/7za.exe b/setup/development/7za.exe new file mode 100644 index 0000000000000000000000000000000000000000..fc8a0bd2f060703f59ab8253869f160ec0c46971 GIT binary patch literal 643072 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²d|Mp;!kG;-o2rfL1 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�K*Y;a3VFDUDMi}Bh{%K2OZP@g_cYZ( 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 Date: Mon, 21 Dec 2015 10:08:45 +0900 Subject: [PATCH 02/20] #150 Modify : DataFormat local from browser loale --- ui/app/util/Formatter.java | 5 ++-- ui/app/util/Util.java | 7 +++-- .../views/component/lockedNotice.scala.html | 2 +- ui/app/views/node/list.scala.html | 29 +++++++++---------- ui/app/views/node/version.scala.html | 8 ++--- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/ui/app/util/Formatter.java b/ui/app/util/Formatter.java index 6a2ae809..76ede3e0 100644 --- a/ui/app/util/Formatter.java +++ b/ui/app/util/Formatter.java @@ -3,6 +3,7 @@ import java.text.DateFormat; import java.util.Date; import java.util.GregorianCalendar; +import java.util.Locale; import org.apache.chemistry.opencmis.client.api.CmisObject; import org.apache.chemistry.opencmis.client.api.Document; @@ -10,9 +11,9 @@ public class Formatter { - public static String calToString(GregorianCalendar gc){ + public static String calToString(GregorianCalendar gc, Locale locale){ Date date = gc.getTime(); - DateFormat df = DateFormat.getInstance(); + DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM, locale); String result = df.format(date); return result; } diff --git a/ui/app/util/Util.java b/ui/app/util/Util.java index 308bf83d..4d6d480e 100644 --- a/ui/app/util/Util.java +++ b/ui/app/util/Util.java @@ -15,6 +15,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; @@ -744,15 +745,15 @@ public static boolean isEditableOnNodeBlank(PropertyDefinition pdf){ !PropertyIds.SECONDARY_OBJECT_TYPE_IDS.equals(pdf.getId()); } - public static String displayValue(CmisObject obj, String propertyId){ + public static String displayValue(CmisObject obj, String propertyId, Locale locale){ if(PropertyIds.CREATED_BY.equals(propertyId)){ return obj.getCreatedBy(); }else if(PropertyIds.CREATION_DATE.equals(propertyId)){ - return Formatter.calToString(obj.getCreationDate()); + return Formatter.calToString(obj.getCreationDate(), locale); } else if(PropertyIds.LAST_MODIFIED_BY.equals(propertyId)){ return obj.getLastModifiedBy(); }else if(PropertyIds.LAST_MODIFICATION_DATE.equals(propertyId)){ - return Formatter.calToString(obj.getLastModificationDate()); + return Formatter.calToString(obj.getLastModificationDate(), locale); }else if(PropertyIds.VERSION_SERIES_CHECKED_OUT_BY.equals(propertyId)){ if(isDocument(obj)){ Document doc = (Document)obj; diff --git a/ui/app/views/component/lockedNotice.scala.html b/ui/app/views/component/lockedNotice.scala.html index 05aaea8a..9c2cfba4 100644 --- a/ui/app/views/component/lockedNotice.scala.html +++ b/ui/app/views/component/lockedNotice.scala.html @@ -3,4 +3,4 @@ @import org.apache.chemistry.opencmis.commons.PropertyIds @(obj:CmisObject) -@Messages("view.node.freeze-copy.cannot-update", Util.displayValue(obj,PropertyIds.VERSION_SERIES_CHECKED_OUT_BY)) \ No newline at end of file +@Messages("view.node.freeze-copy.cannot-update", Util.displayValue(obj,PropertyIds.VERSION_SERIES_CHECKED_OUT_BY, lang.toLocale)) \ No newline at end of file diff --git a/ui/app/views/node/list.scala.html b/ui/app/views/node/list.scala.html index b0bdc53e..6c3d83ec 100644 --- a/ui/app/views/node/list.scala.html +++ b/ui/app/views/node/list.scala.html @@ -29,27 +29,27 @@ @if(document.isVersionSeriesCheckedOut){ } - + @if(Util.hasContentStream(document)){ }else{ } } - + case folder:Folder =>{ } - + case _ =>{ - + } }
    @obj.getName()
    @for(column <- play.Play.application().configuration().getStringList("navigation.column.displayed")){ - @Util.displayValue(obj, column) + @Util.displayValue(obj, column, lang.toLocale) }
    @@ -58,8 +58,8 @@ } -
    - + + } @@ -76,7 +76,7 @@ - + - + + + - - \ No newline at end of file diff --git a/ui/app/views/node/version.scala.html b/ui/app/views/node/version.scala.html index 0d2f1ae8..83969fc0 100644 --- a/ui/app/views/node/version.scala.html +++ b/ui/app/views/node/version.scala.html @@ -25,19 +25,19 @@ @version.getName() @version.getCreatedBy() - @Formatter.calToString(version.getCreationDate()) + @Formatter.calToString(version.getCreationDate(), lang.toLocale) } - + - + \ No newline at end of file + \ No newline at end of file From b74c3f335ae694e86f15b1ba3fc5a5496002a0bf Mon Sep 17 00:00:00 2001 From: git -v Date: Mon, 21 Dec 2015 11:53:48 +0900 Subject: [PATCH 03/20] Modify : Update OpenCmis 0.13 --- ui/build.sbt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/build.sbt b/ui/build.sbt index b7727acf..ca6caa52 100644 --- a/ui/build.sbt +++ b/ui/build.sbt @@ -21,10 +21,10 @@ libraryDependencies ++= Seq( "org.webjars" % "bootstrap" % "3.2.0", "org.webjars" % "jquery" % "1.11.1", "org.webjars" % "jquery-ui" % "1.11.1", - "org.apache.chemistry.opencmis" % "chemistry-opencmis-client-impl" % "0.12.0", - "org.apache.chemistry.opencmis" % "chemistry-opencmis-client-bindings" % "0.12.0", - "org.apache.chemistry.opencmis" % "chemistry-opencmis-client-api" % "0.12.0", - "org.apache.chemistry.opencmis" % "chemistry-opencmis-commons-impl" % "0.12.0", + "org.apache.chemistry.opencmis" % "chemistry-opencmis-client-impl" % "0.13.0", + "org.apache.chemistry.opencmis" % "chemistry-opencmis-client-bindings" % "0.13.0", + "org.apache.chemistry.opencmis" % "chemistry-opencmis-client-api" % "0.13.0", + "org.apache.chemistry.opencmis" % "chemistry-opencmis-commons-impl" % "0.13.0", "org.apache.httpcomponents" % "httpclient" % "4.4-beta1" ) From 964855cf4aec85e7cc8cf93f41fa57e20e6e11e5 Mon Sep 17 00:00:00 2001 From: git -v Date: Mon, 21 Dec 2015 11:54:29 +0900 Subject: [PATCH 04/20] Modify : Update nemakiware repo version --- core/src/main/webapp/WEB-INF/classes/repositories.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/webapp/WEB-INF/classes/repositories.yml b/core/src/main/webapp/WEB-INF/classes/repositories.yml index 18dea8c8..19186f61 100644 --- a/core/src/main/webapp/WEB-INF/classes/repositories.yml +++ b/core/src/main/webapp/WEB-INF/classes/repositories.yml @@ -6,7 +6,7 @@ default: thinClientUri: http://localhost:8080/ui/ vendor: aegif product.name: NemakiWare - product.version: 2.3.4 + product.version: 2.3.7 namespace: http://www.aegif.jp/NemakiWare/ super.users: canopy repositories: From 36b9bb872ddd5071a8bc0c62e712751978c70b35 Mon Sep 17 00:00:00 2001 From: git -v Date: Mon, 21 Dec 2015 18:45:55 +0900 Subject: [PATCH 05/20] Fix : Fix getFolderByPath method. --- .../impl/ContentServiceImpl.java | 2 +- .../java/jp/aegif/nemaki/model/Folder.java | 192 +++++++++--------- 2 files changed, 97 insertions(+), 97 deletions(-) diff --git a/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java index 6c757953..d7658ab8 100644 --- a/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java @@ -166,7 +166,7 @@ public Content getContentByPath(String repositoryId, String path) { // root return contentDaoService.getFolder(repositoryId, rootId); } else if (splittedPath.size() >= 1) { - Content content = contentDaoService.getFolderByPath(repositoryId, rootId); + Content content = contentDaoService.getFolder(repositoryId, rootId); // Get the the leaf node for (int i = 1; i < splittedPath.size(); i++) { String leafName = splittedPath.get(i); diff --git a/core/src/main/java/jp/aegif/nemaki/model/Folder.java b/core/src/main/java/jp/aegif/nemaki/model/Folder.java index 88095d1f..9df68398 100644 --- a/core/src/main/java/jp/aegif/nemaki/model/Folder.java +++ b/core/src/main/java/jp/aegif/nemaki/model/Folder.java @@ -1,96 +1,96 @@ -/******************************************************************************* - * Copyright (c) 2013 aegif. - * - * This file is part of NemakiWare. - * - * NemakiWare 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 3 of the License, or - * (at your option) any later version. - * - * NemakiWare 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 NemakiWare. - * If not, see . - * - * Contributors: - * linzhixing(https://github.com/linzhixing) - initial API and implementation - ******************************************************************************/ -package jp.aegif.nemaki.model; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import jp.aegif.nemaki.util.constant.NodeType; - -import org.codehaus.jackson.annotate.JsonIgnoreProperties; - -/** - * CMIS folder object - * This can file folder/document object. - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class Folder extends Content { - - private List allowedChildTypeIds; - private List renditionIds; - - - public Folder(){ - super(); - setType(NodeType.CMIS_FOLDER.value()); - } - - public Folder(Content c){ - super(c); - setName(c.getName()); - setDescription(c.getDescription()); - setParentId(c.getParentId()); - setAcl(c.getAcl()); - setAclInherited(c.isAclInherited()); - setSubTypeProperties(c.getSubTypeProperties()); - setAspects(c.getAspects()); - setSecondaryIds(c.getSecondaryIds()); - setObjectType(c.getObjectType()); - setChangeToken(c.getChangeToken()); - } - - public List getAllowedChildTypeIds() { - return allowedChildTypeIds; - } - - public void setAllowedChildTypeIds(List allowedChildTypeIds) { - this.allowedChildTypeIds = allowedChildTypeIds; - } - - public List getRenditionIds() { - return renditionIds; - } - - public void setRenditionIds(List renditionIds) { - this.renditionIds = renditionIds; - } - - @Override - public String toString() { - @SuppressWarnings("serial") - Map m = new HashMap() { - { - put("id", getId()); - put("name", getName()); - put("type", getType()); - put("creator", getCreator()); - put("created", getCreated()); - put("modifier", getModifier()); - put("modified", getModified()); - put("parentId", getParentId()); - } - }; - return m.toString(); - } - -} +/******************************************************************************* + * Copyright (c) 2013 aegif. + * + * This file is part of NemakiWare. + * + * NemakiWare 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 3 of the License, or + * (at your option) any later version. + * + * NemakiWare 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 NemakiWare. + * If not, see . + * + * Contributors: + * linzhixing(https://github.com/linzhixing) - initial API and implementation + ******************************************************************************/ +package jp.aegif.nemaki.model; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import jp.aegif.nemaki.util.constant.NodeType; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; + +/** + * CMIS folder object + * This can file folder/document object. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Folder extends Content { + + private List allowedChildTypeIds; + private List renditionIds; + + + public Folder(){ + super(); + setType(NodeType.CMIS_FOLDER.value()); + } + + public Folder(Content c){ + super(c); + setName(c.getName()); + setDescription(c.getDescription()); + setParentId(c.getParentId()); + setAcl(c.getAcl()); + setAclInherited(c.isAclInherited()); + setSubTypeProperties(c.getSubTypeProperties()); + setAspects(c.getAspects()); + setSecondaryIds(c.getSecondaryIds()); + setObjectType(c.getObjectType()); + setChangeToken(c.getChangeToken()); + } + + public List getAllowedChildTypeIds() { + return allowedChildTypeIds; + } + + public void setAllowedChildTypeIds(List allowedChildTypeIds) { + this.allowedChildTypeIds = allowedChildTypeIds; + } + + public List getRenditionIds() { + return renditionIds; + } + + public void setRenditionIds(List renditionIds) { + this.renditionIds = renditionIds; + } + + @Override + public String toString() { + @SuppressWarnings("serial") + Map m = new HashMap() { + { + put("id", getId()); + put("name", getName()); + put("type", getType()); + put("creator", getCreator()); + put("created", getCreated()); + put("modifier", getModifier()); + put("modified", getModified()); + put("parentId", getParentId()); + } + }; + return m.toString(); + } + +} From 2711197b9297df0d101c333603875c23e3bac664 Mon Sep 17 00:00:00 2001 From: git -v Date: Mon, 21 Dec 2015 22:08:21 +0900 Subject: [PATCH 06/20] Modify : show product version --- ui/app/constant/Token.java | 6 ++++-- ui/app/controllers/Application.java | 11 +++++++++-- ui/app/views/menubar.scala.html | 2 ++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ui/app/constant/Token.java b/ui/app/constant/Token.java index f93b5748..6b33b10e 100644 --- a/ui/app/constant/Token.java +++ b/ui/app/constant/Token.java @@ -4,12 +4,14 @@ public interface Token { final String LOGIN_USER_ID = "loginUserId"; final String LOGIN_USER_PASSWORD = "loginUserPassword"; final String LOGIN_USER_IS_ADMIN = "loginUserIsAdmin"; - + + final String NEMAKIWARE_VERSION = "NemakiWareProductVersion"; + final String REST_STATUS = "status"; final String REST_SUCCESS = "success"; final String REST_RESULT = "result"; final String REST_ERROR = "error"; - + final String PRINCIPAL_GENRE_USER = "user"; final String PRINCIPAL_GENRE_GROUP = "group"; } diff --git a/ui/app/controllers/Application.java b/ui/app/controllers/Application.java index d65b8860..280d1e11 100644 --- a/ui/app/controllers/Application.java +++ b/ui/app/controllers/Application.java @@ -2,6 +2,9 @@ import java.util.Map; +import org.apache.chemistry.opencmis.client.api.Session; +import org.apache.chemistry.opencmis.commons.data.RepositoryInfo; + import com.fasterxml.jackson.databind.JsonNode; import constant.Token; @@ -31,10 +34,14 @@ public static Result authenticate(String repositoryId){ session(Token.LOGIN_USER_PASSWORD, loginModel.password); session(Token.LOGIN_USER_IS_ADMIN, String.valueOf(isAdmin(repositoryId, loginModel.id))); session("repositoryId", repositoryId); + session(Token.NEMAKIWARE_VERSION,getVersion(repositoryId)); return redirect(routes.Node.index(repositoryId)); } - - + public static String getVersion(String repositoryId){ + Session session = CmisSessions.getCmisSession(repositoryId, session()); + RepositoryInfo repo = session.getRepositoryInfo(); + return repo.getProductVersion(); + } private static boolean isAdmin(String repositoryId, String id){ boolean isAdmin = false; diff --git a/ui/app/views/menubar.scala.html b/ui/app/views/menubar.scala.html index 855b100e..57af8b8d 100644 --- a/ui/app/views/menubar.scala.html +++ b/ui/app/views/menubar.scala.html @@ -44,6 +44,7 @@ } + } @@ -57,6 +58,7 @@ +
  1. From ebdc549a24a51b0baa8ffa188175899bf427ed7b Mon Sep 17 00:00:00 2001 From: git -v Date: Fri, 25 Dec 2015 17:02:45 +0900 Subject: [PATCH 07/20] Modify : detail log --- .../aspect/impl/ExceptionServiceImpl.java | 2391 ++++++++--------- .../aspect/impl/PermissionServiceImpl.java | 866 +++--- 2 files changed, 1634 insertions(+), 1623 deletions(-) diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/ExceptionServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/ExceptionServiceImpl.java index 51bfb58d..a054bc6b 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/ExceptionServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/ExceptionServiceImpl.java @@ -1,1196 +1,1195 @@ -/******************************************************************************* - * Copyright (c) 2013 aegif. - * - * This file is part of NemakiWare. - * - * NemakiWare 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 3 of the License, or - * (at your option) any later version. - * - * NemakiWare 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 Licensealong with NemakiWare. - * If not, see . - * - * Contributors: - * linzhixing(https://github.com/linzhixing) - initial API and implementation - ******************************************************************************/ -package jp.aegif.nemaki.cmis.aspect.impl; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.apache.chemistry.opencmis.commons.PropertyIds; -import org.apache.chemistry.opencmis.commons.data.ContentStream; -import org.apache.chemistry.opencmis.commons.data.Properties; -import org.apache.chemistry.opencmis.commons.data.PropertyData; -import org.apache.chemistry.opencmis.commons.data.PropertyDecimal; -import org.apache.chemistry.opencmis.commons.data.PropertyString; -import org.apache.chemistry.opencmis.commons.definitions.Choice; -import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition; -import org.apache.chemistry.opencmis.commons.definitions.PermissionDefinition; -import org.apache.chemistry.opencmis.commons.definitions.PropertyDecimalDefinition; -import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition; -import org.apache.chemistry.opencmis.commons.definitions.PropertyIntegerDefinition; -import org.apache.chemistry.opencmis.commons.definitions.PropertyStringDefinition; -import org.apache.chemistry.opencmis.commons.definitions.RelationshipTypeDefinition; -import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition; -import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer; -import org.apache.chemistry.opencmis.commons.definitions.TypeMutability; -import org.apache.chemistry.opencmis.commons.enums.AclPropagation; -import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; -import org.apache.chemistry.opencmis.commons.enums.CapabilityOrderBy; -import org.apache.chemistry.opencmis.commons.enums.Cardinality; -import org.apache.chemistry.opencmis.commons.enums.ContentStreamAllowed; -import org.apache.chemistry.opencmis.commons.enums.PropertyType; -import org.apache.chemistry.opencmis.commons.enums.VersioningState; -import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException; -import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException; -import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException; -import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException; -import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException; -import org.apache.chemistry.opencmis.commons.exceptions.CmisStreamNotSupportedException; -import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException; -import org.apache.chemistry.opencmis.commons.exceptions.CmisVersioningException; -import org.apache.chemistry.opencmis.commons.server.CallContext; -import org.apache.chemistry.opencmis.commons.spi.Holder; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.collections.MapUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; - -import jp.aegif.nemaki.businesslogic.ContentService; -import jp.aegif.nemaki.businesslogic.PrincipalService; -import jp.aegif.nemaki.cmis.aspect.ExceptionService; -import jp.aegif.nemaki.cmis.aspect.PermissionService; -import jp.aegif.nemaki.cmis.aspect.type.TypeManager; -import jp.aegif.nemaki.cmis.factory.info.RepositoryInfoMap; -import jp.aegif.nemaki.model.Acl; -import jp.aegif.nemaki.model.Change; -import jp.aegif.nemaki.model.Content; -import jp.aegif.nemaki.model.Document; -import jp.aegif.nemaki.model.Folder; -import jp.aegif.nemaki.model.User; -import jp.aegif.nemaki.model.VersionSeries; -import jp.aegif.nemaki.util.DataUtil; -import jp.aegif.nemaki.util.constant.DomainType; - -public class ExceptionServiceImpl implements ExceptionService, - ApplicationContextAware { - private TypeManager typeManager; - private ContentService contentService; - private PermissionService permissionService; - private RepositoryInfoMap repositoryInfoMap; - private PrincipalService principalService; - - private static final Log log = LogFactory - .getLog(ExceptionServiceImpl.class); - - private final BigInteger HTTP_STATUS_CODE_400 = BigInteger.valueOf(400); - private final BigInteger HTTP_STATUS_CODE_403 = BigInteger.valueOf(403); - private final BigInteger HTTP_STATUS_CODE_404 = BigInteger.valueOf(404); - private final BigInteger HTTP_STATUS_CODE_405 = BigInteger.valueOf(405); - private final BigInteger HTTP_STATUS_CODE_409 = BigInteger.valueOf(409); - private final BigInteger HTTP_STATUS_CODE_500 = BigInteger.valueOf(500); - - @Override - public void invalidArgument(String msg) { - throw new CmisInvalidArgumentException(msg, HTTP_STATUS_CODE_400); - } - - @Override - public void invalidArgumentRequired(String argumentName) { - throw new CmisInvalidArgumentException(argumentName + " must be set", - HTTP_STATUS_CODE_400); - } - - @Override - public void invalidArgumentRequired(String argumentName, Object argument) { - if (argument == null) { - invalidArgumentRequired(argumentName); - } - } - - @Override - public void invalidArgumentRequiredString(String argumentName, - String argument) { - if (isEmptyString(argument)) { - invalidArgumentRequired(argumentName); - } - } - - @Override - public void invalidArgumentRequiredHolderString(String argumentName, - Holder argument) { - if (argument == null || isEmptyString(argument.getValue())) { - invalidArgumentRequired(argumentName); - } - - } - - @Override - public void invalidArgumentRootFolder(String repositoryId, Content content) { - if (contentService.isRoot(repositoryId, content)) - invalidArgument("Cannot specify the root folder as an input parameter"); - } - - @Override - public void invalidArgumentFolderId(Folder folder, String folderId) { - if (folder == null) { - String msg = "This objectId is not a folder id"; - invalidArgument(buildMsgWithId(msg, folderId)); - } - } - - @Override - public void invalidArgumentDepth(BigInteger depth) { - if (depth == BigInteger.ZERO) { - invalidArgument("Depth must not be zero"); - } else if (depth == BigInteger.valueOf(-1)) { - invalidArgument("Depth must not be less than -1"); - } - } - - private boolean isEmptyString(String s) { - if (s != null && s.length() != 0) { - return false; - } else { - return true; - } - } - - @Override - public void invalidArgumentRequiredCollection(String argumentName, - Collection collection) { - if (CollectionUtils.isEmpty(collection)) - invalidArgument(argumentName); - } - - @Override - public void invalidArgumentRequiredParentFolderId(String repositoryId, String folderId) { - if (!repositoryInfoMap.get(repositoryId).getCapabilities().isMultifilingSupported()) - invalidArgumentRequiredString("folderId", folderId); - } - - @Override - public void invalidArgumentOrderBy(String repositoryId, String orderBy) { - if (repositoryInfoMap.get(repositoryId).getCapabilities().getOrderByCapability() == CapabilityOrderBy.NONE - && orderBy != null) - invalidArgument("OrderBy capability is not supported"); - } - - @Override - public void invalidArgumentChangeEventNotAvailable( - String repositoryId, Holder changeLogToken) { - if (changeLogToken != null && changeLogToken.getValue() != null) { - Change change = contentService.getChangeEvent(repositoryId, changeLogToken - .getValue()); - if (change == null) - invalidArgument("changeLogToken:" + changeLogToken.getValue() - + " does not exist"); - } - - } - - @Override - public void invalidArgumentCreatableType(String repositoryId, TypeDefinition type) { - String msg = ""; - - String parentId = type.getParentTypeId(); - if (typeManager.getTypeById(repositoryId, parentId) == null) { - msg = "Specified parent type does not exist"; - } else { - TypeDefinition parent = typeManager.getTypeById(repositoryId, parentId) - .getTypeDefinition(); - if (parent.getTypeMutability() == null) { - msg = "Specified parent type does not have TypeMutability"; - } else { - boolean canCreate = (parent.getTypeMutability() == null) ? false - : true; - if (!canCreate) { - msg = "Specified parent type has TypeMutability.canCreate = false"; - } - } - } - - if (!StringUtils.isEmpty(msg)) { - msg = msg + " [objectTypeId = " + type.getId() + "]"; - invalidArgument(msg); - } - } - - @Override - public void invalidArgumentUpdatableType(TypeDefinition type) { - String msg = ""; - TypeMutability typeMutability = type.getTypeMutability(); - boolean canUpdate = (typeMutability.canUpdate() == null) ? false - : typeMutability.canUpdate(); - if (!canUpdate) { - msg = "Specified type is not updatable"; - msg = msg + " [objectTypeId = " + type.getId() + "]"; - invalidArgument(msg); - } - } - - @Override - public void invalidArgumentDeletableType(String repositoryId, String typeId) { - TypeDefinition type = typeManager.getTypeDefinition(repositoryId, typeId); - - String msg = ""; - TypeMutability typeMutability = type.getTypeMutability(); - boolean canUpdate = (typeMutability.canDelete() == null) ? true - : typeMutability.canDelete(); - if (!canUpdate) { - msg = "Specified type is not deletable"; - msg = msg + " [objectTypeId = " + type.getId() + "]"; - invalidArgument(msg); - } - - } - - @Override - public void invalidArgumentDoesNotExistType(String repositoryId, String typeId) { - String msg = ""; - - TypeDefinition type = typeManager.getTypeDefinition(repositoryId, typeId); - if (type == null) { - msg = "Specified type does not exist"; - msg = msg + " [objectTypeId = " + typeId + "]"; - invalidArgument(msg); - } - } - - @Override - public void invalidArgumentSecondaryTypeIds(String repositoryId, Properties properties) { - if (properties == null) - return; - Map> map = properties.getProperties(); - if (MapUtils.isEmpty(map)) - return; - - List results = new ArrayList(); - PropertyData ids = map.get(PropertyIds.SECONDARY_OBJECT_TYPE_IDS); - if (ids == null || CollectionUtils.isEmpty(ids.getValues())) - return; - for (Object _id : ids.getValues()) { - String id = (String) _id; - TypeDefinitionContainer tdc = typeManager.getTypeById(repositoryId, id); - if (tdc == null) { - results.add(id); - } - } - - if (CollectionUtils.isNotEmpty(results)) { - String msg = "Invalid cmis:SecondaryObjectTypeIds are provided:" - + StringUtils.join(results, ","); - invalidArgument(msg); - } - } - - @Override - public void objectNotFound(DomainType type, Object object, String id, - String msg) { - if (object == null) - throw new CmisObjectNotFoundException(msg, HTTP_STATUS_CODE_404); - } - - @Override - public void objectNotFound(DomainType type, Object object, String id) { - String msg = "[" + type.value() + "Id:" + id + "]" - + "The specified object is not found"; - objectNotFound(type, object, id, msg); - } - - @Override - public void objectNotFoundVersionSeries(String id, Collection collection) { - if (CollectionUtils.isEmpty(collection)) { - String msg = "[VersionSeriesId:" + id + "]" - + "The specified version series is not found"; - throw new CmisObjectNotFoundException(msg, HTTP_STATUS_CODE_404); - } - } - - @Override - public void objectNotFoundParentFolder(String repositoryId, String id, Content content) { - if (!repositoryInfoMap.get(repositoryId).getCapabilities().isMultifilingSupported()) - objectNotFound(DomainType.OBJECT, content, id, - "The specified parent folder is not found"); - } - - /** - * - */ - // TODO Show also stack errors - @Override - public void permissionDenied(CallContext context, String repositoryId, - String key, Content content) { - String baseTypeId = content.getType(); - Acl acl = contentService.calculateAcl(repositoryId, content); - permissionDeniedInternal(context, repositoryId, key, acl, baseTypeId, content); - } - - private void permissionDeniedInternal(CallContext callContext, String repositoryId, - String key, Acl acl, String baseTypeId, Content content) { - - if (!permissionService.checkPermission(callContext, repositoryId, key, - acl, baseTypeId, content)) { - String msg = "Permission Denied!"; - throw new CmisPermissionDeniedException(msg, HTTP_STATUS_CODE_403); - } - } - - @Override - public void perimissionAdmin(CallContext context, String repositoryId) { - User admin = principalService.getAdmin(repositoryId); - - if (!admin.getUserId().equals(context.getUsername())) { - String msg = "This operation if permitted only for administrator"; - throw new CmisPermissionDeniedException(msg, HTTP_STATUS_CODE_403); - } - } - - /** - * - * NOTE:Check the condition before calling this method - */ - @Override - public void constraint(String objectId, String msg) { - throw new CmisConstraintException(buildMsgWithId(msg, objectId), - HTTP_STATUS_CODE_409); - } - - private void constraint(String msg) { - throw new CmisConstraintException(msg, HTTP_STATUS_CODE_409); - } - - @Override - public void constraintBaseTypeId(String repositoryId, - Properties properties, BaseTypeId baseTypeId) { - String objectTypeId = DataUtil.getObjectTypeId(properties); - TypeDefinition td = typeManager.getTypeDefinition(repositoryId, objectTypeId); - - if (!td.getBaseTypeId().equals(baseTypeId)) - constraint(null, - "cmis:objectTypeId is not an object type whose base tyep is " - + baseTypeId); - } - - @Override - public void constraintAllowedChildObjectTypeId(Folder folder, - Properties childProperties) { - List allowedTypes = folder.getAllowedChildTypeIds(); - - // If cmis:allowedCHildTypeIds is not set, all types are allowed. - if (!CollectionUtils.isEmpty(allowedTypes)) { - String childType = DataUtil.getIdProperty(childProperties, - PropertyIds.OBJECT_TYPE_ID); - if (!allowedTypes.contains(childType)) { - String objectId = DataUtil.getIdProperty(childProperties, - PropertyIds.OBJECT_ID); - constraint( - objectId, - "cmis:objectTypeId=" - + childType - + " is not in the list of AllowedChildObjectTypeIds of the parent folder"); - } - } - } - - @Override - public void constraintPropertyValue(String repositoryId, - TypeDefinition typeDefinition, Properties properties, String objectId) { - Map> propertyDefinitions = typeDefinition - .getPropertyDefinitions(); - - // Adding secondary types and its properties MAY be done in the same - // operation - List secIds = DataUtil.getIdListProperty(properties, - PropertyIds.SECONDARY_OBJECT_TYPE_IDS); - if (CollectionUtils.isNotEmpty(secIds)) { - for (String secId : secIds) { - TypeDefinition sec = typeManager.getTypeById(repositoryId, secId) - .getTypeDefinition(); - for (Entry> entry : sec - .getPropertyDefinitions().entrySet()) { - if (!propertyDefinitions.containsKey(entry.getKey())) { - propertyDefinitions.put(entry.getKey(), - entry.getValue()); - } - } - } - } - - for (PropertyData _pd : properties.getPropertyList()) { - PropertyData pd = (PropertyData) _pd; - PropertyDefinition propertyDefinition = (PropertyDefinition) propertyDefinitions - .get(pd.getId()); - // If an input property is not defined one, output error. - if (propertyDefinition == null) - constraint(objectId, "An undefined property is provided!"); - - // Check "required" flag - if (propertyDefinition.isRequired() - && !DataUtil.valueExist(pd.getValues())) - constraint(objectId, "An required property is not provided!"); - - // Check choices - constraintChoices(propertyDefinition, pd, objectId); - - // Check min/max length - switch (propertyDefinition.getPropertyType()) { - case STRING: - constraintStringPropertyValue(propertyDefinition, pd, objectId); - break; - case DECIMAL: - constraintDecimalPropertyValue(propertyDefinition, pd, objectId); - case INTEGER: - constraintIntegerPropertyValue(propertyDefinition, pd, objectId); - break; - default: - break; - } - } - } - - private void constraintChoices(PropertyDefinition definition, - PropertyData propertyData, String objectId) { - // Check OpenChoice - boolean openChoice = (definition.isOpenChoice() == null) ? true : false; - if (openChoice) - return; - - List data = propertyData.getValues(); - // null or blank String value should be permitted within any choice list - if (CollectionUtils.isEmpty(data)) - return; - - List> choices = definition.getChoices(); - if (CollectionUtils.isEmpty(choices) || CollectionUtils.isEmpty(data)) - return; - - boolean included = false; - if (definition.getCardinality() == Cardinality.SINGLE) { - T d = data.get(0); - - if (d instanceof String && StringUtils.isBlank((String) d) - || d == null) { - return; - } else { - for (Choice choice : choices) { - List value = choice.getValue(); - T v = value.get(0); - if (v.equals(d)) { - included = true; - break; - } - } - } - - } else if (definition.getCardinality() == Cardinality.MULTI) { - List values = new ArrayList(); - for (Choice choice : choices) { - values.addAll(choice.getValue()); - } - - for (T d : data) { - if (values.contains(d)) { - included = true; - } else { - if (d instanceof String && StringUtils.isBlank((String) d) - || d == null) { - included = true; - } else { - included = false; - break; - } - } - } - } - - if (!included) { - constraint(objectId, propertyData.getId() - + " property value must be one of choices"); - } - } - - private void constraintIntegerPropertyValue( - PropertyDefinition definition, PropertyData propertyData, - String objectId) { - final String msg = "AN INTEGER property violates the range constraints"; - BigInteger val = BigInteger - .valueOf((Long) propertyData.getFirstValue()); - - BigInteger min = ((PropertyIntegerDefinition) definition).getMinValue(); - if (min != null && min.compareTo(val) > 0) { - constraint(objectId, msg); - } - - BigInteger max = ((PropertyIntegerDefinition) definition).getMinValue(); - if (max != null && max.compareTo(val) < 0) { - constraint(objectId, msg); - } - } - - private void constraintDecimalPropertyValue( - PropertyDefinition definition, PropertyData propertyData, - String objectId) { - final String msg = "An DECIMAL property violates the range constraints"; - - if (!(propertyData instanceof PropertyDecimal)) - return; - BigDecimal val = ((PropertyDecimal) propertyData).getFirstValue(); - - BigDecimal min = ((PropertyDecimalDefinition) definition).getMinValue(); - if (min != null && min.compareTo(val) > 0) { - constraint(objectId, msg); - } - - BigDecimal max = ((PropertyDecimalDefinition) definition).getMaxValue(); - if (max != null && max.compareTo(val) > 0) { - constraint(objectId, msg); - } - } - - private void constraintStringPropertyValue( - PropertyDefinition definition, PropertyData propertyData, - String objectId) { - final String msg = "An STRING property violates the length constraints"; - if (!(propertyData instanceof PropertyString)) - return; - String val = ((PropertyString) propertyData).getFirstValue(); - if (StringUtils.isEmpty(val)) - return; - BigInteger length = BigInteger.valueOf(val.length()); - BigInteger max = ((PropertyStringDefinition) definition).getMaxLength(); - if (max != null && max.compareTo(length) < 0) { - constraint(objectId, msg); - } - } - - @Override - public void constraintControllableVersionable( - DocumentTypeDefinition documentTypeDefinition, - VersioningState versioningState, String objectId) { - if (!documentTypeDefinition.isVersionable() - && (versioningState != null && versioningState != VersioningState.NONE)) { - String msg = "Versioning state must not be set for a non-versionable object-type"; - throw new CmisConstraintException(buildMsgWithId(msg, objectId), - HTTP_STATUS_CODE_409); - } - if (documentTypeDefinition.isVersionable() - && versioningState == VersioningState.NONE) { - String msg = "Versioning state is set for a non-versionable object-type"; - throw new CmisConstraintException(buildMsgWithId(msg, objectId), - HTTP_STATUS_CODE_409); - } - - } - - @Override - public void constraintCotrollablePolicies(TypeDefinition typeDefinition, - List policies, Properties properties) { - if (!typeDefinition.isControllablePolicy() - && !CollectionUtils.isEmpty(policies)) { - String msg = "Policies cannnot be provided to a non-controllablePolicy object-type"; - constraint(getObjectId(properties), msg); - } - } - - @Override - public void constraintCotrollableAcl(TypeDefinition typeDefinition, - org.apache.chemistry.opencmis.commons.data.Acl addAces, - org.apache.chemistry.opencmis.commons.data.Acl removeAces, - Properties properties) { - // TODO ignore removeAces? - boolean aclIsEmpty = (addAces == null) - || (addAces != null && CollectionUtils.isEmpty(addAces - .getAces())) ? true : false; - if (!typeDefinition.isControllableAcl() && !aclIsEmpty) { - constraint(getObjectId(properties), - "Acl cannnot be provided to a non-controllableAcl object-type"); - } - } - - @Override - public void constraintPermissionDefined( - String repositoryId, org.apache.chemistry.opencmis.commons.data.Acl acl, String objectId) { - boolean aclIsEmpty = (acl == null) - || (acl != null && CollectionUtils.isEmpty(acl.getAces())) ? true - : false; - List definitions = repositoryInfoMap.get(repositoryId) - .getAclCapabilities().getPermissions(); - List definedIds = new ArrayList(); - for (PermissionDefinition pdf : definitions) { - definedIds.add(pdf.getId()); - } - - if (!aclIsEmpty) { - for (org.apache.chemistry.opencmis.commons.data.Ace ace : acl - .getAces()) { - List permissions = ace.getPermissions(); - for (String p : permissions) { - if (!definedIds.contains(p)) { - constraint(objectId, - "A provided ACE includes an unsupported permission"); - } - } - } - } - } - - @Override - public void constraintAllowedSourceTypes( - RelationshipTypeDefinition relationshipTypeDefinition, - Content source) { - List allowed = relationshipTypeDefinition - .getAllowedSourceTypeIds(); - if (CollectionUtils.isNotEmpty(allowed)) { - if (!allowed.contains((source.getObjectType()))) - constraint(source.getId(), - "The source object's type is not allowed for the relationship"); - } - } - - @Override - public void constraintAllowedTargetTypes( - RelationshipTypeDefinition relationshipTypeDefinition, - Content target) { - List allowed = relationshipTypeDefinition - .getAllowedTargetTypeIds(); - if (CollectionUtils.isNotEmpty(allowed)) { - if (!allowed.contains(target.getObjectType())) - constraint(target.getId(), - "The target object's type is not allowed for the relationship"); - } - } - - @Override - public void constraintVersionable(String repositoryId, String typeId) { - DocumentTypeDefinition type = (DocumentTypeDefinition) typeManager - .getTypeDefinition(repositoryId, typeId); - if (!type.isVersionable()) { - String msg = "Object type: " + type.getId() + " is not versionbale"; - throw new CmisConstraintException(msg, HTTP_STATUS_CODE_409); - } - - } - - @Override - public void constraintAlreadyCheckedOut(String repositoryId, Document document) { - VersionSeries vs = contentService.getVersionSeries(repositoryId, document); - if (vs.isVersionSeriesCheckedOut()) { - if (!(document.isPrivateWorkingCopy())) { - constraint(document.getId(), - "The version series is already checked out"); - } - } - } - - @Override - public void constraintUpdateWhenCheckedOut(String repositoryId, - String currentUserId, Document document) { - VersionSeries vs = contentService.getVersionSeries(repositoryId, document); - if (vs.isVersionSeriesCheckedOut()) { - if (document.isPrivateWorkingCopy()) { - // Can update by only the use who has checked it out - String whoCheckedOut = vs.getVersionSeriesCheckedOutBy(); - if (!currentUserId.equals(whoCheckedOut)) { - constraint( - document.getId(), - "This private working copy can be modified only by the user who has checked it out. "); - } - } else { - // All versions except for PWC are locked. - constraint(document.getId(), - "All versions except for PWC are locked when checked out."); - } - } - - } - - @Override - public void constraintAclPropagationDoesNotMatch( - AclPropagation aclPropagation) { - // Do nothing - } - - @Override - public void constraintContentStreamRequired(String repositoryId, Document document) { - String objectTypeId = document.getObjectType(); - DocumentTypeDefinition td = (DocumentTypeDefinition) typeManager - .getTypeDefinition(repositoryId, objectTypeId); - if (td.getContentStreamAllowed() == ContentStreamAllowed.REQUIRED) { - if (document.getAttachmentNodeId() == null - || contentService.getAttachment(repositoryId, document - .getAttachmentNodeId()) == null) { - constraint(document.getId(), - "This document type does not allow no content stream"); - } - } - } - - @Override - public void constraintContentStreamRequired( - DocumentTypeDefinition typeDefinition, ContentStream contentStream) { - if (ContentStreamAllowed.REQUIRED.equals(typeDefinition - .getContentStreamAllowed())) { - if (contentStream == null || contentStream.getStream() == null) { - constraint("[typeId=" - + typeDefinition.getId() - + "]This document type does not allow no content stream"); - } - } - } - - @Override - public void constraintOnlyLeafTypeDefinition(String repositoryId, String objectTypeId) { - TypeDefinitionContainer tdc = typeManager.getTypeById(repositoryId, objectTypeId); - if (!CollectionUtils.isEmpty(tdc.getChildren())) { - String msg = "Cannot delete a type definition which has sub types" - + " [objectTypeId = " + objectTypeId + "]"; - throw new CmisConstraintException(msg, HTTP_STATUS_CODE_409); - } - } - - @Override - public void constraintObjectsStillExist(String repositoryId, String objectTypeId) { - if (contentService.existContent(repositoryId, objectTypeId)) { - String msg = "There still exists objects of the specified object type" - + " [objectTypeId = " + objectTypeId + "]"; - throw new CmisConstraintException(msg, HTTP_STATUS_CODE_409); - } - } - - @Override - public void constraintDuplicatePropertyDefinition( - String repositoryId, TypeDefinition typeDefinition) { - Map> props = typeDefinition - .getPropertyDefinitions(); - if (MapUtils.isNotEmpty(props)) { - Set keys = props.keySet(); - TypeDefinition parent = typeManager - .getTypeDefinition(repositoryId, typeDefinition.getParentTypeId()); - Map> parentProps = parent - .getPropertyDefinitions(); - if (MapUtils.isNotEmpty(parentProps)) { - Set parentKeys = parentProps.keySet(); - for (String key : keys) { - if (parentKeys.contains(key)) { - String msg = "Duplicate property definition with parent type definition" - + " [property id = " + key + "]"; - throw new CmisConstraintException(msg, - HTTP_STATUS_CODE_409); - } - } - } - } - } - - @Override - public void constraintUpdatePropertyDefinition( - PropertyDefinition update, PropertyDefinition old) { - constraintUpdatePropertyDefinitionHelper(update, old); - } - - private PropertyDefinition constraintUpdatePropertyDefinitionHelper( - PropertyDefinition update, PropertyDefinition old) { - String msg = ""; - // objField.setName(field.getName()); - // objField.setValue(field.getValue()); - // return objField; - if (!old.isInherited().equals(update.isInherited())) { - msg += "'inherited' cannot be modified"; - } - - if (typeManager.getSystemPropertyIds().contains(update.getId())) { - msg += "CMIS-defined property definition cannot be modified"; - } - - if (Boolean.FALSE.equals(old.isRequired()) - && Boolean.TRUE.equals(update.isRequired())) { - msg += "'required' cannot be modified from Optional to Required"; - constraint(msg); - } - - if (Boolean.TRUE.equals(old.isOpenChoice()) - && Boolean.FALSE.equals(update.isOpenChoice())) { - msg += "'openChoice' cannot be modified from true to false"; - constraint(msg); - } - - if (Boolean.FALSE.equals(update.isOpenChoice())) { - constraintChoicesRestriction(update, old); - } - - constraintRestrictedValidation(update, old); - - if (!old.getPropertyType().equals(update.getPropertyType())) { - msg += "'property type' cannot be modified"; - constraint(msg); - } - - if (!old.getCardinality().equals(update.getCardinality())) { - msg += "'cardinality' cannot be modified"; - constraint(msg); - } - return update; - } - - private void constraintChoicesRestriction(PropertyDefinition update, - PropertyDefinition old) { - String msg = update.getId() + ":"; - - List updateValues = flattenChoiceValues(update.getChoices()); - List oldValues = flattenChoiceValues(old.getChoices()); - if (!updateValues.containsAll(oldValues)) { - msg += "'choices' values must not be removed if 'openChoice' is false"; - constraint(msg); - } - } - - private List flattenChoiceValues(List> choices) { - if (CollectionUtils.isEmpty(choices)) - return null; - - List result = new ArrayList(); - for (Choice choice : choices) { - List value = choice.getValue(); - if (CollectionUtils.isEmpty(value)) - continue; - for (T v : value) { - result.add(v); - } - - result.addAll(flattenChoiceValues(choice.getChoice())); - } - return result; - } - - private void constraintRestrictedValidation(PropertyDefinition update, - PropertyDefinition old) { - switch (update.getPropertyType()) { - case BOOLEAN: - break; - case DATETIME: - break; - case DECIMAL: - constraintRestrictedDecimalValidation(update, old); - break; - case HTML: - break; - case ID: - break; - case INTEGER: - constraintRestrictedIntegerValidation(update, old); - break; - case STRING: - constraintRestrictedStringValidation(update, old); - break; - case URI: - break; - default: - break; - } - } - - private void constraintRestrictedDecimalValidation( - PropertyDefinition update, PropertyDefinition old) { - PropertyDecimalDefinition _update = (PropertyDecimalDefinition) update; - PropertyDecimalDefinition _old = (PropertyDecimalDefinition) old; - // When minValue is restricted, throw an error - minRestriction(_update.getMinValue(), _old.getMinValue(), - _update.getId()); - // When minValue is restricted, throw an error - maxRestriction(_update.getMaxValue(), _old.getMaxValue(), - _update.getId(), null); - } - - private void constraintRestrictedIntegerValidation( - PropertyDefinition update, PropertyDefinition old) { - PropertyIntegerDefinition _update = (PropertyIntegerDefinition) update; - PropertyIntegerDefinition _old = (PropertyIntegerDefinition) old; - // When minValue is restricted, throw an error - minRestriction(_update.getMinValue(), _old.getMinValue(), - _update.getId()); - // When minValue is restricted, throw an error - maxRestriction(_update.getMaxValue(), _old.getMaxValue(), - _update.getId(), _update.getPropertyType()); - } - - private void constraintRestrictedStringValidation( - PropertyDefinition update, PropertyDefinition old) { - PropertyStringDefinition _update = (PropertyStringDefinition) update; - PropertyStringDefinition _old = (PropertyStringDefinition) old; - // When minValue is restricted, throw an error - maxRestriction(_update.getMaxLength(), _old.getMaxLength(), - _update.getId(), _update.getPropertyType()); - } - - private void minRestriction(Comparable update, Comparable old, - String propertyId) { - // When minValue is restricted, throw an error - boolean flag = false; - String msg = propertyId + ":"; - if (old == null) { - if (update != null) { - flag = true; - } - } else { - if (update != null) { - if (old.compareTo(update) < 0) { - flag = true; - } - } - } - if (flag) { - msg += "'minValue' cannot be further restricted"; - constraint(msg); - } - } - - private void maxRestriction(Comparable update, Comparable old, - String propertyId, PropertyType propertyType) { - // When minValue is restricted, throw an error - boolean flag = false; - String msg = propertyId + ":"; - if (old == null) { - if (update != null) { - flag = true; - } - } else { - if (update != null) { - if (old.compareTo(update) > 0) { - flag = true; - } - } - } - if (flag) { - if (propertyType.equals(PropertyType.STRING)) { - msg += "'maxLength' cannot be further restricted"; - } else { - msg += "'maxValue' cannot be further restricted"; - } - constraint(msg); - } - } - - @Override - public void constraintQueryName(PropertyDefinition propertyDefinition) { - - String msg = propertyDefinition.getId() + ":"; - String queryName = propertyDefinition.getQueryName(); - - if (StringUtils.isEmpty(queryName)) - constraint(msg + "'queryName' is null"); - - final String space = " "; - final String comma = ","; - final String dubleQuotation = "\""; - final String singleQuotaion = "\'"; - final String backslash = "\\\\"; - final String period = "\\."; - final String openParenthesis = "\\("; - final String closeParenthesis = "\\)"; - - if (queryName.matches(buildContainRegEx(space)) - || queryName.matches(buildContainRegEx(comma)) - || queryName.matches(buildContainRegEx(dubleQuotation)) - || queryName.matches(buildContainRegEx(singleQuotaion)) - || queryName.matches(buildContainRegEx(backslash)) - || queryName.matches(buildContainRegEx(period)) - || queryName.matches(buildContainRegEx(openParenthesis)) - || queryName.matches(buildContainRegEx(closeParenthesis))) { - constraint(msg - + "invalid character for 'queryName'. See spec 2.1.2.1.3"); - } - } - - private String buildContainRegEx(String contained) { - return ".*" + contained + ".*"; - } - - @Override - public void constraintContentStreamDownload(String repositoryId, Document document) { - DocumentTypeDefinition documentTypeDefinition = (DocumentTypeDefinition) typeManager - .getTypeDefinition(repositoryId, document); - ContentStreamAllowed csa = documentTypeDefinition - .getContentStreamAllowed(); - if (ContentStreamAllowed.NOTALLOWED == csa - || ContentStreamAllowed.ALLOWED == csa - && StringUtils.isBlank(document.getAttachmentNodeId())) { - constraint(document.getId(), - "This document has no ContentStream. getContentStream is not supported."); - } - } - - @Override - public void constraintRenditionStreamDownload(Content content, - String streamId) { - List renditions = content.getRenditionIds(); - if (CollectionUtils.isEmpty(renditions) - || !renditions.contains(streamId)) { - constraint(content.getId(), - "This document has no rendition specified with " + streamId); - } - } - - @Override - public void constraintImmutable(String repositoryId, - Document document, TypeDefinition typeDefinition) { - Boolean defaultVal = (Boolean) typeManager.getSingleDefaultValue( - PropertyIds.IS_IMMUTABLE, typeDefinition.getId(), repositoryId); - - boolean flag = false; - if (document.isImmutable() == null) { - if (defaultVal != null && defaultVal) { - flag = true; - } - } else { - if (document.isImmutable()) { - flag = true; - } - } - - if (flag) { - constraint(document.getId(), - "Immutable document cannot be updated/deleted"); - } - } - - @Override - public void constraintPropertyDefinition(TypeDefinition typeDefinition, - PropertyDefinition propertyDefinition) { - - String typeId = typeDefinition.getId(); - String propertyId = propertyDefinition.getId(); - - if (propertyDefinition.isOrderable() - && propertyDefinition.getCardinality() == Cardinality.MULTI) { - String msg = DataUtil.buildPrefixTypeProperty(typeId, propertyId) - + "PropertyDefinition violates the specification"; - constraint(msg); - } - } - - public void constraintDeleteRootFolder(String repositoryId, String objectId){ - String rootFolderId = repositoryInfoMap.get(repositoryId).getRootFolderId(); - if(rootFolderId.equals(objectId)){ - constraint(objectId, "Cannot delete root folder"); - } - } - - @Override - public void contentAlreadyExists(Content content, Boolean overwriteFlag) { - if (!overwriteFlag) { - Document document = (Document) content; // FIXME - String attachmentNodeId = document.getAttachmentNodeId(); // FIXME - // getAttachmentNodes - - if (attachmentNodeId != null) { - String msg = "Can't overwrite the content stream when overwriteFlag is false"; - throw new CmisContentAlreadyExistsException(buildMsgWithId(msg, - content.getId()), HTTP_STATUS_CODE_409); - } - } - } - - @Override - public void streamNotSupported( - DocumentTypeDefinition documentTypeDefinition, - ContentStream contentStream) { - if (documentTypeDefinition.getContentStreamAllowed() == ContentStreamAllowed.NOTALLOWED - && contentStream != null) { - String msg = "A Content stream must not be included"; - throw new CmisStreamNotSupportedException(msg, HTTP_STATUS_CODE_403); - } - } - - /** - * - */ - @Override - public void versioning(Document doc) { - if (!doc.isLatestVersion() && !doc.isPrivateWorkingCopy()) { - String msg = "The operation is not allowed on a non-current version of a document"; - throw new CmisVersioningException(buildMsgWithId(msg, doc.getId()), - HTTP_STATUS_CODE_409); - } - } - - // TODO implement! - @Override - public void nameConstraintViolation(Properties properties, - Folder parentFolder) { - // If name conflicts, modify names by the repository without outputting - // error - if (parentFolder == null) { - - } else { - - } - } - - @Override - public void updateConflict(Content content, Holder changeToken) { - if ((changeToken == null || changeToken.getValue() == null)) { - throw new CmisUpdateConflictException( - "Change token is required to update", HTTP_STATUS_CODE_409); - } else if (!changeToken.getValue().equals(content.getChangeToken())) { - throw new CmisUpdateConflictException( - "Cannot update because the changeToken conflicts", - HTTP_STATUS_CODE_409); - } - } - - private String buildMsgWithId(String msg, String objectId) { - if (objectId == null) - objectId = ""; - return msg + " [cmis:objectId = " + objectId + "]"; - } - - private String getObjectId(Properties properties) { - return DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID); - } - - /** - * Setter - */ - @Override - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - } - - public void setTypeManager(TypeManager typeManager) { - this.typeManager = typeManager; - } - - public void setContentService(ContentService contentService) { - this.contentService = contentService; - } - - public void setPermissionService(PermissionService permissionService) { - this.permissionService = permissionService; - } - - public void setRepositoryInfoMap(RepositoryInfoMap repositoryInfoMap) { - this.repositoryInfoMap = repositoryInfoMap; - } - - public void setPrincipalService(PrincipalService principalService) { - this.principalService = principalService; - } -} +/******************************************************************************* + * Copyright (c) 2013 aegif. + * + * This file is part of NemakiWare. + * + * NemakiWare 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 3 of the License, or + * (at your option) any later version. + * + * NemakiWare 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 Licensealong with NemakiWare. + * If not, see . + * + * Contributors: + * linzhixing(https://github.com/linzhixing) - initial API and implementation + ******************************************************************************/ +package jp.aegif.nemaki.cmis.aspect.impl; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.chemistry.opencmis.commons.PropertyIds; +import org.apache.chemistry.opencmis.commons.data.ContentStream; +import org.apache.chemistry.opencmis.commons.data.Properties; +import org.apache.chemistry.opencmis.commons.data.PropertyData; +import org.apache.chemistry.opencmis.commons.data.PropertyDecimal; +import org.apache.chemistry.opencmis.commons.data.PropertyString; +import org.apache.chemistry.opencmis.commons.definitions.Choice; +import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition; +import org.apache.chemistry.opencmis.commons.definitions.PermissionDefinition; +import org.apache.chemistry.opencmis.commons.definitions.PropertyDecimalDefinition; +import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition; +import org.apache.chemistry.opencmis.commons.definitions.PropertyIntegerDefinition; +import org.apache.chemistry.opencmis.commons.definitions.PropertyStringDefinition; +import org.apache.chemistry.opencmis.commons.definitions.RelationshipTypeDefinition; +import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition; +import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer; +import org.apache.chemistry.opencmis.commons.definitions.TypeMutability; +import org.apache.chemistry.opencmis.commons.enums.AclPropagation; +import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; +import org.apache.chemistry.opencmis.commons.enums.CapabilityOrderBy; +import org.apache.chemistry.opencmis.commons.enums.Cardinality; +import org.apache.chemistry.opencmis.commons.enums.ContentStreamAllowed; +import org.apache.chemistry.opencmis.commons.enums.PropertyType; +import org.apache.chemistry.opencmis.commons.enums.VersioningState; +import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException; +import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException; +import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException; +import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException; +import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException; +import org.apache.chemistry.opencmis.commons.exceptions.CmisStreamNotSupportedException; +import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException; +import org.apache.chemistry.opencmis.commons.exceptions.CmisVersioningException; +import org.apache.chemistry.opencmis.commons.server.CallContext; +import org.apache.chemistry.opencmis.commons.spi.Holder; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +import jp.aegif.nemaki.businesslogic.ContentService; +import jp.aegif.nemaki.businesslogic.PrincipalService; +import jp.aegif.nemaki.cmis.aspect.ExceptionService; +import jp.aegif.nemaki.cmis.aspect.PermissionService; +import jp.aegif.nemaki.cmis.aspect.type.TypeManager; +import jp.aegif.nemaki.cmis.factory.info.RepositoryInfoMap; +import jp.aegif.nemaki.model.Acl; +import jp.aegif.nemaki.model.Change; +import jp.aegif.nemaki.model.Content; +import jp.aegif.nemaki.model.Document; +import jp.aegif.nemaki.model.Folder; +import jp.aegif.nemaki.model.User; +import jp.aegif.nemaki.model.VersionSeries; +import jp.aegif.nemaki.util.DataUtil; +import jp.aegif.nemaki.util.constant.DomainType; + +public class ExceptionServiceImpl implements ExceptionService, + ApplicationContextAware { + private TypeManager typeManager; + private ContentService contentService; + private PermissionService permissionService; + private RepositoryInfoMap repositoryInfoMap; + private PrincipalService principalService; + + private static final Log log = LogFactory + .getLog(ExceptionServiceImpl.class); + + private final BigInteger HTTP_STATUS_CODE_400 = BigInteger.valueOf(400); + private final BigInteger HTTP_STATUS_CODE_403 = BigInteger.valueOf(403); + private final BigInteger HTTP_STATUS_CODE_404 = BigInteger.valueOf(404); + private final BigInteger HTTP_STATUS_CODE_405 = BigInteger.valueOf(405); + private final BigInteger HTTP_STATUS_CODE_409 = BigInteger.valueOf(409); + private final BigInteger HTTP_STATUS_CODE_500 = BigInteger.valueOf(500); + + @Override + public void invalidArgument(String msg) { + throw new CmisInvalidArgumentException(msg, HTTP_STATUS_CODE_400); + } + + @Override + public void invalidArgumentRequired(String argumentName) { + throw new CmisInvalidArgumentException(argumentName + " must be set", + HTTP_STATUS_CODE_400); + } + + @Override + public void invalidArgumentRequired(String argumentName, Object argument) { + if (argument == null) { + invalidArgumentRequired(argumentName); + } + } + + @Override + public void invalidArgumentRequiredString(String argumentName, + String argument) { + if (isEmptyString(argument)) { + invalidArgumentRequired(argumentName); + } + } + + @Override + public void invalidArgumentRequiredHolderString(String argumentName, + Holder argument) { + if (argument == null || isEmptyString(argument.getValue())) { + invalidArgumentRequired(argumentName); + } + + } + + @Override + public void invalidArgumentRootFolder(String repositoryId, Content content) { + if (contentService.isRoot(repositoryId, content)) + invalidArgument("Cannot specify the root folder as an input parameter"); + } + + @Override + public void invalidArgumentFolderId(Folder folder, String folderId) { + if (folder == null) { + String msg = "This objectId is not a folder id"; + invalidArgument(buildMsgWithId(msg, folderId)); + } + } + + @Override + public void invalidArgumentDepth(BigInteger depth) { + if (depth == BigInteger.ZERO) { + invalidArgument("Depth must not be zero"); + } else if (depth == BigInteger.valueOf(-1)) { + invalidArgument("Depth must not be less than -1"); + } + } + + private boolean isEmptyString(String s) { + if (s != null && s.length() != 0) { + return false; + } else { + return true; + } + } + + @Override + public void invalidArgumentRequiredCollection(String argumentName, + Collection collection) { + if (CollectionUtils.isEmpty(collection)) + invalidArgument(argumentName); + } + + @Override + public void invalidArgumentRequiredParentFolderId(String repositoryId, String folderId) { + if (!repositoryInfoMap.get(repositoryId).getCapabilities().isMultifilingSupported()) + invalidArgumentRequiredString("folderId", folderId); + } + + @Override + public void invalidArgumentOrderBy(String repositoryId, String orderBy) { + if (repositoryInfoMap.get(repositoryId).getCapabilities().getOrderByCapability() == CapabilityOrderBy.NONE + && orderBy != null) + invalidArgument("OrderBy capability is not supported"); + } + + @Override + public void invalidArgumentChangeEventNotAvailable( + String repositoryId, Holder changeLogToken) { + if (changeLogToken != null && changeLogToken.getValue() != null) { + Change change = contentService.getChangeEvent(repositoryId, changeLogToken + .getValue()); + if (change == null) + invalidArgument("changeLogToken:" + changeLogToken.getValue() + + " does not exist"); + } + + } + + @Override + public void invalidArgumentCreatableType(String repositoryId, TypeDefinition type) { + String msg = ""; + + String parentId = type.getParentTypeId(); + if (typeManager.getTypeById(repositoryId, parentId) == null) { + msg = "Specified parent type does not exist"; + } else { + TypeDefinition parent = typeManager.getTypeById(repositoryId, parentId) + .getTypeDefinition(); + if (parent.getTypeMutability() == null) { + msg = "Specified parent type does not have TypeMutability"; + } else { + boolean canCreate = (parent.getTypeMutability() == null) ? false + : true; + if (!canCreate) { + msg = "Specified parent type has TypeMutability.canCreate = false"; + } + } + } + + if (!StringUtils.isEmpty(msg)) { + msg = msg + " [objectTypeId = " + type.getId() + "]"; + invalidArgument(msg); + } + } + + @Override + public void invalidArgumentUpdatableType(TypeDefinition type) { + String msg = ""; + TypeMutability typeMutability = type.getTypeMutability(); + boolean canUpdate = (typeMutability.canUpdate() == null) ? false + : typeMutability.canUpdate(); + if (!canUpdate) { + msg = "Specified type is not updatable"; + msg = msg + " [objectTypeId = " + type.getId() + "]"; + invalidArgument(msg); + } + } + + @Override + public void invalidArgumentDeletableType(String repositoryId, String typeId) { + TypeDefinition type = typeManager.getTypeDefinition(repositoryId, typeId); + + String msg = ""; + TypeMutability typeMutability = type.getTypeMutability(); + boolean canUpdate = (typeMutability.canDelete() == null) ? true + : typeMutability.canDelete(); + if (!canUpdate) { + msg = "Specified type is not deletable"; + msg = msg + " [objectTypeId = " + type.getId() + "]"; + invalidArgument(msg); + } + + } + + @Override + public void invalidArgumentDoesNotExistType(String repositoryId, String typeId) { + String msg = ""; + + TypeDefinition type = typeManager.getTypeDefinition(repositoryId, typeId); + if (type == null) { + msg = "Specified type does not exist"; + msg = msg + " [objectTypeId = " + typeId + "]"; + invalidArgument(msg); + } + } + + @Override + public void invalidArgumentSecondaryTypeIds(String repositoryId, Properties properties) { + if (properties == null) + return; + Map> map = properties.getProperties(); + if (MapUtils.isEmpty(map)) + return; + + List results = new ArrayList(); + PropertyData ids = map.get(PropertyIds.SECONDARY_OBJECT_TYPE_IDS); + if (ids == null || CollectionUtils.isEmpty(ids.getValues())) + return; + for (Object _id : ids.getValues()) { + String id = (String) _id; + TypeDefinitionContainer tdc = typeManager.getTypeById(repositoryId, id); + if (tdc == null) { + results.add(id); + } + } + + if (CollectionUtils.isNotEmpty(results)) { + String msg = "Invalid cmis:SecondaryObjectTypeIds are provided:" + + StringUtils.join(results, ","); + invalidArgument(msg); + } + } + + @Override + public void objectNotFound(DomainType type, Object object, String id, + String msg) { + if (object == null) + throw new CmisObjectNotFoundException(msg, HTTP_STATUS_CODE_404); + } + + @Override + public void objectNotFound(DomainType type, Object object, String id) { + String msg = "[" + type.value() + "Id:" + id + "]" + + "The specified object is not found"; + objectNotFound(type, object, id, msg); + } + + @Override + public void objectNotFoundVersionSeries(String id, Collection collection) { + if (CollectionUtils.isEmpty(collection)) { + String msg = "[VersionSeriesId:" + id + "]" + + "The specified version series is not found"; + throw new CmisObjectNotFoundException(msg, HTTP_STATUS_CODE_404); + } + } + + @Override + public void objectNotFoundParentFolder(String repositoryId, String id, Content content) { + if (!repositoryInfoMap.get(repositoryId).getCapabilities().isMultifilingSupported()) + objectNotFound(DomainType.OBJECT, content, id, + "The specified parent folder is not found"); + } + + /** + * + */ + // TODO Show also stack errors + @Override + public void permissionDenied(CallContext context, String repositoryId, + String key, Content content) { + String baseTypeId = content.getType(); + Acl acl = contentService.calculateAcl(repositoryId, content); + permissionDeniedInternal(context, repositoryId, key, acl, baseTypeId, content); + } + + private void permissionDeniedInternal(CallContext callContext, String repositoryId, + String key, Acl acl, String baseTypeId, Content content) { + + if (!permissionService.checkPermission(callContext, repositoryId, key, acl, baseTypeId, content)) { + String msg = String.format( "Permission Denied! repositoryId=%s key=%s acl=%s contentName=%s ", repositoryId, key, acl, baseTypeId, content.getName()) ; + throw new CmisPermissionDeniedException(msg, HTTP_STATUS_CODE_403); + } + } + + @Override + public void perimissionAdmin(CallContext context, String repositoryId) { + User admin = principalService.getAdmin(repositoryId); + + if (!admin.getUserId().equals(context.getUsername())) { + String msg = "This operation if permitted only for administrator"; + throw new CmisPermissionDeniedException(msg, HTTP_STATUS_CODE_403); + } + } + + /** + * + * NOTE:Check the condition before calling this method + */ + @Override + public void constraint(String objectId, String msg) { + throw new CmisConstraintException(buildMsgWithId(msg, objectId), + HTTP_STATUS_CODE_409); + } + + private void constraint(String msg) { + throw new CmisConstraintException(msg, HTTP_STATUS_CODE_409); + } + + @Override + public void constraintBaseTypeId(String repositoryId, + Properties properties, BaseTypeId baseTypeId) { + String objectTypeId = DataUtil.getObjectTypeId(properties); + TypeDefinition td = typeManager.getTypeDefinition(repositoryId, objectTypeId); + + if (!td.getBaseTypeId().equals(baseTypeId)) + constraint(null, + "cmis:objectTypeId is not an object type whose base tyep is " + + baseTypeId); + } + + @Override + public void constraintAllowedChildObjectTypeId(Folder folder, + Properties childProperties) { + List allowedTypes = folder.getAllowedChildTypeIds(); + + // If cmis:allowedCHildTypeIds is not set, all types are allowed. + if (!CollectionUtils.isEmpty(allowedTypes)) { + String childType = DataUtil.getIdProperty(childProperties, + PropertyIds.OBJECT_TYPE_ID); + if (!allowedTypes.contains(childType)) { + String objectId = DataUtil.getIdProperty(childProperties, + PropertyIds.OBJECT_ID); + constraint( + objectId, + "cmis:objectTypeId=" + + childType + + " is not in the list of AllowedChildObjectTypeIds of the parent folder"); + } + } + } + + @Override + public void constraintPropertyValue(String repositoryId, + TypeDefinition typeDefinition, Properties properties, String objectId) { + Map> propertyDefinitions = typeDefinition + .getPropertyDefinitions(); + + // Adding secondary types and its properties MAY be done in the same + // operation + List secIds = DataUtil.getIdListProperty(properties, + PropertyIds.SECONDARY_OBJECT_TYPE_IDS); + if (CollectionUtils.isNotEmpty(secIds)) { + for (String secId : secIds) { + TypeDefinition sec = typeManager.getTypeById(repositoryId, secId) + .getTypeDefinition(); + for (Entry> entry : sec + .getPropertyDefinitions().entrySet()) { + if (!propertyDefinitions.containsKey(entry.getKey())) { + propertyDefinitions.put(entry.getKey(), + entry.getValue()); + } + } + } + } + + for (PropertyData _pd : properties.getPropertyList()) { + PropertyData pd = (PropertyData) _pd; + PropertyDefinition propertyDefinition = (PropertyDefinition) propertyDefinitions + .get(pd.getId()); + // If an input property is not defined one, output error. + if (propertyDefinition == null) + constraint(objectId, "An undefined property is provided!"); + + // Check "required" flag + if (propertyDefinition.isRequired() + && !DataUtil.valueExist(pd.getValues())) + constraint(objectId, "An required property is not provided!"); + + // Check choices + constraintChoices(propertyDefinition, pd, objectId); + + // Check min/max length + switch (propertyDefinition.getPropertyType()) { + case STRING: + constraintStringPropertyValue(propertyDefinition, pd, objectId); + break; + case DECIMAL: + constraintDecimalPropertyValue(propertyDefinition, pd, objectId); + case INTEGER: + constraintIntegerPropertyValue(propertyDefinition, pd, objectId); + break; + default: + break; + } + } + } + + private void constraintChoices(PropertyDefinition definition, + PropertyData propertyData, String objectId) { + // Check OpenChoice + boolean openChoice = (definition.isOpenChoice() == null) ? true : false; + if (openChoice) + return; + + List data = propertyData.getValues(); + // null or blank String value should be permitted within any choice list + if (CollectionUtils.isEmpty(data)) + return; + + List> choices = definition.getChoices(); + if (CollectionUtils.isEmpty(choices) || CollectionUtils.isEmpty(data)) + return; + + boolean included = false; + if (definition.getCardinality() == Cardinality.SINGLE) { + T d = data.get(0); + + if (d instanceof String && StringUtils.isBlank((String) d) + || d == null) { + return; + } else { + for (Choice choice : choices) { + List value = choice.getValue(); + T v = value.get(0); + if (v.equals(d)) { + included = true; + break; + } + } + } + + } else if (definition.getCardinality() == Cardinality.MULTI) { + List values = new ArrayList(); + for (Choice choice : choices) { + values.addAll(choice.getValue()); + } + + for (T d : data) { + if (values.contains(d)) { + included = true; + } else { + if (d instanceof String && StringUtils.isBlank((String) d) + || d == null) { + included = true; + } else { + included = false; + break; + } + } + } + } + + if (!included) { + constraint(objectId, propertyData.getId() + + " property value must be one of choices"); + } + } + + private void constraintIntegerPropertyValue( + PropertyDefinition definition, PropertyData propertyData, + String objectId) { + final String msg = "AN INTEGER property violates the range constraints"; + BigInteger val = BigInteger + .valueOf((Long) propertyData.getFirstValue()); + + BigInteger min = ((PropertyIntegerDefinition) definition).getMinValue(); + if (min != null && min.compareTo(val) > 0) { + constraint(objectId, msg); + } + + BigInteger max = ((PropertyIntegerDefinition) definition).getMinValue(); + if (max != null && max.compareTo(val) < 0) { + constraint(objectId, msg); + } + } + + private void constraintDecimalPropertyValue( + PropertyDefinition definition, PropertyData propertyData, + String objectId) { + final String msg = "An DECIMAL property violates the range constraints"; + + if (!(propertyData instanceof PropertyDecimal)) + return; + BigDecimal val = ((PropertyDecimal) propertyData).getFirstValue(); + + BigDecimal min = ((PropertyDecimalDefinition) definition).getMinValue(); + if (min != null && min.compareTo(val) > 0) { + constraint(objectId, msg); + } + + BigDecimal max = ((PropertyDecimalDefinition) definition).getMaxValue(); + if (max != null && max.compareTo(val) > 0) { + constraint(objectId, msg); + } + } + + private void constraintStringPropertyValue( + PropertyDefinition definition, PropertyData propertyData, + String objectId) { + final String msg = "An STRING property violates the length constraints"; + if (!(propertyData instanceof PropertyString)) + return; + String val = ((PropertyString) propertyData).getFirstValue(); + if (StringUtils.isEmpty(val)) + return; + BigInteger length = BigInteger.valueOf(val.length()); + BigInteger max = ((PropertyStringDefinition) definition).getMaxLength(); + if (max != null && max.compareTo(length) < 0) { + constraint(objectId, msg); + } + } + + @Override + public void constraintControllableVersionable( + DocumentTypeDefinition documentTypeDefinition, + VersioningState versioningState, String objectId) { + if (!documentTypeDefinition.isVersionable() + && (versioningState != null && versioningState != VersioningState.NONE)) { + String msg = "Versioning state must not be set for a non-versionable object-type"; + throw new CmisConstraintException(buildMsgWithId(msg, objectId), + HTTP_STATUS_CODE_409); + } + if (documentTypeDefinition.isVersionable() + && versioningState == VersioningState.NONE) { + String msg = "Versioning state is set for a non-versionable object-type"; + throw new CmisConstraintException(buildMsgWithId(msg, objectId), + HTTP_STATUS_CODE_409); + } + + } + + @Override + public void constraintCotrollablePolicies(TypeDefinition typeDefinition, + List policies, Properties properties) { + if (!typeDefinition.isControllablePolicy() + && !CollectionUtils.isEmpty(policies)) { + String msg = "Policies cannnot be provided to a non-controllablePolicy object-type"; + constraint(getObjectId(properties), msg); + } + } + + @Override + public void constraintCotrollableAcl(TypeDefinition typeDefinition, + org.apache.chemistry.opencmis.commons.data.Acl addAces, + org.apache.chemistry.opencmis.commons.data.Acl removeAces, + Properties properties) { + // TODO ignore removeAces? + boolean aclIsEmpty = (addAces == null) + || (addAces != null && CollectionUtils.isEmpty(addAces + .getAces())) ? true : false; + if (!typeDefinition.isControllableAcl() && !aclIsEmpty) { + constraint(getObjectId(properties), + "Acl cannnot be provided to a non-controllableAcl object-type"); + } + } + + @Override + public void constraintPermissionDefined( + String repositoryId, org.apache.chemistry.opencmis.commons.data.Acl acl, String objectId) { + boolean aclIsEmpty = (acl == null) + || (acl != null && CollectionUtils.isEmpty(acl.getAces())) ? true + : false; + List definitions = repositoryInfoMap.get(repositoryId) + .getAclCapabilities().getPermissions(); + List definedIds = new ArrayList(); + for (PermissionDefinition pdf : definitions) { + definedIds.add(pdf.getId()); + } + + if (!aclIsEmpty) { + for (org.apache.chemistry.opencmis.commons.data.Ace ace : acl + .getAces()) { + List permissions = ace.getPermissions(); + for (String p : permissions) { + if (!definedIds.contains(p)) { + constraint(objectId, + "A provided ACE includes an unsupported permission"); + } + } + } + } + } + + @Override + public void constraintAllowedSourceTypes( + RelationshipTypeDefinition relationshipTypeDefinition, + Content source) { + List allowed = relationshipTypeDefinition + .getAllowedSourceTypeIds(); + if (CollectionUtils.isNotEmpty(allowed)) { + if (!allowed.contains((source.getObjectType()))) + constraint(source.getId(), + "The source object's type is not allowed for the relationship"); + } + } + + @Override + public void constraintAllowedTargetTypes( + RelationshipTypeDefinition relationshipTypeDefinition, + Content target) { + List allowed = relationshipTypeDefinition + .getAllowedTargetTypeIds(); + if (CollectionUtils.isNotEmpty(allowed)) { + if (!allowed.contains(target.getObjectType())) + constraint(target.getId(), + "The target object's type is not allowed for the relationship"); + } + } + + @Override + public void constraintVersionable(String repositoryId, String typeId) { + DocumentTypeDefinition type = (DocumentTypeDefinition) typeManager + .getTypeDefinition(repositoryId, typeId); + if (!type.isVersionable()) { + String msg = "Object type: " + type.getId() + " is not versionbale"; + throw new CmisConstraintException(msg, HTTP_STATUS_CODE_409); + } + + } + + @Override + public void constraintAlreadyCheckedOut(String repositoryId, Document document) { + VersionSeries vs = contentService.getVersionSeries(repositoryId, document); + if (vs.isVersionSeriesCheckedOut()) { + if (!(document.isPrivateWorkingCopy())) { + constraint(document.getId(), + "The version series is already checked out"); + } + } + } + + @Override + public void constraintUpdateWhenCheckedOut(String repositoryId, + String currentUserId, Document document) { + VersionSeries vs = contentService.getVersionSeries(repositoryId, document); + if (vs.isVersionSeriesCheckedOut()) { + if (document.isPrivateWorkingCopy()) { + // Can update by only the use who has checked it out + String whoCheckedOut = vs.getVersionSeriesCheckedOutBy(); + if (!currentUserId.equals(whoCheckedOut)) { + constraint( + document.getId(), + "This private working copy can be modified only by the user who has checked it out. "); + } + } else { + // All versions except for PWC are locked. + constraint(document.getId(), + "All versions except for PWC are locked when checked out."); + } + } + + } + + @Override + public void constraintAclPropagationDoesNotMatch( + AclPropagation aclPropagation) { + // Do nothing + } + + @Override + public void constraintContentStreamRequired(String repositoryId, Document document) { + String objectTypeId = document.getObjectType(); + DocumentTypeDefinition td = (DocumentTypeDefinition) typeManager + .getTypeDefinition(repositoryId, objectTypeId); + if (td.getContentStreamAllowed() == ContentStreamAllowed.REQUIRED) { + if (document.getAttachmentNodeId() == null + || contentService.getAttachment(repositoryId, document + .getAttachmentNodeId()) == null) { + constraint(document.getId(), + "This document type does not allow no content stream"); + } + } + } + + @Override + public void constraintContentStreamRequired( + DocumentTypeDefinition typeDefinition, ContentStream contentStream) { + if (ContentStreamAllowed.REQUIRED.equals(typeDefinition + .getContentStreamAllowed())) { + if (contentStream == null || contentStream.getStream() == null) { + constraint("[typeId=" + + typeDefinition.getId() + + "]This document type does not allow no content stream"); + } + } + } + + @Override + public void constraintOnlyLeafTypeDefinition(String repositoryId, String objectTypeId) { + TypeDefinitionContainer tdc = typeManager.getTypeById(repositoryId, objectTypeId); + if (!CollectionUtils.isEmpty(tdc.getChildren())) { + String msg = "Cannot delete a type definition which has sub types" + + " [objectTypeId = " + objectTypeId + "]"; + throw new CmisConstraintException(msg, HTTP_STATUS_CODE_409); + } + } + + @Override + public void constraintObjectsStillExist(String repositoryId, String objectTypeId) { + if (contentService.existContent(repositoryId, objectTypeId)) { + String msg = "There still exists objects of the specified object type" + + " [objectTypeId = " + objectTypeId + "]"; + throw new CmisConstraintException(msg, HTTP_STATUS_CODE_409); + } + } + + @Override + public void constraintDuplicatePropertyDefinition( + String repositoryId, TypeDefinition typeDefinition) { + Map> props = typeDefinition + .getPropertyDefinitions(); + if (MapUtils.isNotEmpty(props)) { + Set keys = props.keySet(); + TypeDefinition parent = typeManager + .getTypeDefinition(repositoryId, typeDefinition.getParentTypeId()); + Map> parentProps = parent + .getPropertyDefinitions(); + if (MapUtils.isNotEmpty(parentProps)) { + Set parentKeys = parentProps.keySet(); + for (String key : keys) { + if (parentKeys.contains(key)) { + String msg = "Duplicate property definition with parent type definition" + + " [property id = " + key + "]"; + throw new CmisConstraintException(msg, + HTTP_STATUS_CODE_409); + } + } + } + } + } + + @Override + public void constraintUpdatePropertyDefinition( + PropertyDefinition update, PropertyDefinition old) { + constraintUpdatePropertyDefinitionHelper(update, old); + } + + private PropertyDefinition constraintUpdatePropertyDefinitionHelper( + PropertyDefinition update, PropertyDefinition old) { + String msg = ""; + // objField.setName(field.getName()); + // objField.setValue(field.getValue()); + // return objField; + if (!old.isInherited().equals(update.isInherited())) { + msg += "'inherited' cannot be modified"; + } + + if (typeManager.getSystemPropertyIds().contains(update.getId())) { + msg += "CMIS-defined property definition cannot be modified"; + } + + if (Boolean.FALSE.equals(old.isRequired()) + && Boolean.TRUE.equals(update.isRequired())) { + msg += "'required' cannot be modified from Optional to Required"; + constraint(msg); + } + + if (Boolean.TRUE.equals(old.isOpenChoice()) + && Boolean.FALSE.equals(update.isOpenChoice())) { + msg += "'openChoice' cannot be modified from true to false"; + constraint(msg); + } + + if (Boolean.FALSE.equals(update.isOpenChoice())) { + constraintChoicesRestriction(update, old); + } + + constraintRestrictedValidation(update, old); + + if (!old.getPropertyType().equals(update.getPropertyType())) { + msg += "'property type' cannot be modified"; + constraint(msg); + } + + if (!old.getCardinality().equals(update.getCardinality())) { + msg += "'cardinality' cannot be modified"; + constraint(msg); + } + return update; + } + + private void constraintChoicesRestriction(PropertyDefinition update, + PropertyDefinition old) { + String msg = update.getId() + ":"; + + List updateValues = flattenChoiceValues(update.getChoices()); + List oldValues = flattenChoiceValues(old.getChoices()); + if (!updateValues.containsAll(oldValues)) { + msg += "'choices' values must not be removed if 'openChoice' is false"; + constraint(msg); + } + } + + private List flattenChoiceValues(List> choices) { + if (CollectionUtils.isEmpty(choices)) + return null; + + List result = new ArrayList(); + for (Choice choice : choices) { + List value = choice.getValue(); + if (CollectionUtils.isEmpty(value)) + continue; + for (T v : value) { + result.add(v); + } + + result.addAll(flattenChoiceValues(choice.getChoice())); + } + return result; + } + + private void constraintRestrictedValidation(PropertyDefinition update, + PropertyDefinition old) { + switch (update.getPropertyType()) { + case BOOLEAN: + break; + case DATETIME: + break; + case DECIMAL: + constraintRestrictedDecimalValidation(update, old); + break; + case HTML: + break; + case ID: + break; + case INTEGER: + constraintRestrictedIntegerValidation(update, old); + break; + case STRING: + constraintRestrictedStringValidation(update, old); + break; + case URI: + break; + default: + break; + } + } + + private void constraintRestrictedDecimalValidation( + PropertyDefinition update, PropertyDefinition old) { + PropertyDecimalDefinition _update = (PropertyDecimalDefinition) update; + PropertyDecimalDefinition _old = (PropertyDecimalDefinition) old; + // When minValue is restricted, throw an error + minRestriction(_update.getMinValue(), _old.getMinValue(), + _update.getId()); + // When minValue is restricted, throw an error + maxRestriction(_update.getMaxValue(), _old.getMaxValue(), + _update.getId(), null); + } + + private void constraintRestrictedIntegerValidation( + PropertyDefinition update, PropertyDefinition old) { + PropertyIntegerDefinition _update = (PropertyIntegerDefinition) update; + PropertyIntegerDefinition _old = (PropertyIntegerDefinition) old; + // When minValue is restricted, throw an error + minRestriction(_update.getMinValue(), _old.getMinValue(), + _update.getId()); + // When minValue is restricted, throw an error + maxRestriction(_update.getMaxValue(), _old.getMaxValue(), + _update.getId(), _update.getPropertyType()); + } + + private void constraintRestrictedStringValidation( + PropertyDefinition update, PropertyDefinition old) { + PropertyStringDefinition _update = (PropertyStringDefinition) update; + PropertyStringDefinition _old = (PropertyStringDefinition) old; + // When minValue is restricted, throw an error + maxRestriction(_update.getMaxLength(), _old.getMaxLength(), + _update.getId(), _update.getPropertyType()); + } + + private void minRestriction(Comparable update, Comparable old, + String propertyId) { + // When minValue is restricted, throw an error + boolean flag = false; + String msg = propertyId + ":"; + if (old == null) { + if (update != null) { + flag = true; + } + } else { + if (update != null) { + if (old.compareTo(update) < 0) { + flag = true; + } + } + } + if (flag) { + msg += "'minValue' cannot be further restricted"; + constraint(msg); + } + } + + private void maxRestriction(Comparable update, Comparable old, + String propertyId, PropertyType propertyType) { + // When minValue is restricted, throw an error + boolean flag = false; + String msg = propertyId + ":"; + if (old == null) { + if (update != null) { + flag = true; + } + } else { + if (update != null) { + if (old.compareTo(update) > 0) { + flag = true; + } + } + } + if (flag) { + if (propertyType.equals(PropertyType.STRING)) { + msg += "'maxLength' cannot be further restricted"; + } else { + msg += "'maxValue' cannot be further restricted"; + } + constraint(msg); + } + } + + @Override + public void constraintQueryName(PropertyDefinition propertyDefinition) { + + String msg = propertyDefinition.getId() + ":"; + String queryName = propertyDefinition.getQueryName(); + + if (StringUtils.isEmpty(queryName)) + constraint(msg + "'queryName' is null"); + + final String space = " "; + final String comma = ","; + final String dubleQuotation = "\""; + final String singleQuotaion = "\'"; + final String backslash = "\\\\"; + final String period = "\\."; + final String openParenthesis = "\\("; + final String closeParenthesis = "\\)"; + + if (queryName.matches(buildContainRegEx(space)) + || queryName.matches(buildContainRegEx(comma)) + || queryName.matches(buildContainRegEx(dubleQuotation)) + || queryName.matches(buildContainRegEx(singleQuotaion)) + || queryName.matches(buildContainRegEx(backslash)) + || queryName.matches(buildContainRegEx(period)) + || queryName.matches(buildContainRegEx(openParenthesis)) + || queryName.matches(buildContainRegEx(closeParenthesis))) { + constraint(msg + + "invalid character for 'queryName'. See spec 2.1.2.1.3"); + } + } + + private String buildContainRegEx(String contained) { + return ".*" + contained + ".*"; + } + + @Override + public void constraintContentStreamDownload(String repositoryId, Document document) { + DocumentTypeDefinition documentTypeDefinition = (DocumentTypeDefinition) typeManager + .getTypeDefinition(repositoryId, document); + ContentStreamAllowed csa = documentTypeDefinition + .getContentStreamAllowed(); + if (ContentStreamAllowed.NOTALLOWED == csa + || ContentStreamAllowed.ALLOWED == csa + && StringUtils.isBlank(document.getAttachmentNodeId())) { + constraint(document.getId(), + "This document has no ContentStream. getContentStream is not supported."); + } + } + + @Override + public void constraintRenditionStreamDownload(Content content, + String streamId) { + List renditions = content.getRenditionIds(); + if (CollectionUtils.isEmpty(renditions) + || !renditions.contains(streamId)) { + constraint(content.getId(), + "This document has no rendition specified with " + streamId); + } + } + + @Override + public void constraintImmutable(String repositoryId, + Document document, TypeDefinition typeDefinition) { + Boolean defaultVal = (Boolean) typeManager.getSingleDefaultValue( + PropertyIds.IS_IMMUTABLE, typeDefinition.getId(), repositoryId); + + boolean flag = false; + if (document.isImmutable() == null) { + if (defaultVal != null && defaultVal) { + flag = true; + } + } else { + if (document.isImmutable()) { + flag = true; + } + } + + if (flag) { + constraint(document.getId(), + "Immutable document cannot be updated/deleted"); + } + } + + @Override + public void constraintPropertyDefinition(TypeDefinition typeDefinition, + PropertyDefinition propertyDefinition) { + + String typeId = typeDefinition.getId(); + String propertyId = propertyDefinition.getId(); + + if (propertyDefinition.isOrderable() + && propertyDefinition.getCardinality() == Cardinality.MULTI) { + String msg = DataUtil.buildPrefixTypeProperty(typeId, propertyId) + + "PropertyDefinition violates the specification"; + constraint(msg); + } + } + + public void constraintDeleteRootFolder(String repositoryId, String objectId){ + String rootFolderId = repositoryInfoMap.get(repositoryId).getRootFolderId(); + if(rootFolderId.equals(objectId)){ + constraint(objectId, "Cannot delete root folder"); + } + } + + @Override + public void contentAlreadyExists(Content content, Boolean overwriteFlag) { + if (!overwriteFlag) { + Document document = (Document) content; // FIXME + String attachmentNodeId = document.getAttachmentNodeId(); // FIXME + // getAttachmentNodes + + if (attachmentNodeId != null) { + String msg = "Can't overwrite the content stream when overwriteFlag is false"; + throw new CmisContentAlreadyExistsException(buildMsgWithId(msg, + content.getId()), HTTP_STATUS_CODE_409); + } + } + } + + @Override + public void streamNotSupported( + DocumentTypeDefinition documentTypeDefinition, + ContentStream contentStream) { + if (documentTypeDefinition.getContentStreamAllowed() == ContentStreamAllowed.NOTALLOWED + && contentStream != null) { + String msg = "A Content stream must not be included"; + throw new CmisStreamNotSupportedException(msg, HTTP_STATUS_CODE_403); + } + } + + /** + * + */ + @Override + public void versioning(Document doc) { + if (!doc.isLatestVersion() && !doc.isPrivateWorkingCopy()) { + String msg = "The operation is not allowed on a non-current version of a document"; + throw new CmisVersioningException(buildMsgWithId(msg, doc.getId()), + HTTP_STATUS_CODE_409); + } + } + + // TODO implement! + @Override + public void nameConstraintViolation(Properties properties, + Folder parentFolder) { + // If name conflicts, modify names by the repository without outputting + // error + if (parentFolder == null) { + + } else { + + } + } + + @Override + public void updateConflict(Content content, Holder changeToken) { + if ((changeToken == null || changeToken.getValue() == null)) { + throw new CmisUpdateConflictException( + "Change token is required to update", HTTP_STATUS_CODE_409); + } else if (!changeToken.getValue().equals(content.getChangeToken())) { + throw new CmisUpdateConflictException( + "Cannot update because the changeToken conflicts", + HTTP_STATUS_CODE_409); + } + } + + private String buildMsgWithId(String msg, String objectId) { + if (objectId == null) + objectId = ""; + return msg + " [cmis:objectId = " + objectId + "]"; + } + + private String getObjectId(Properties properties) { + return DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID); + } + + /** + * Setter + */ + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + } + + public void setTypeManager(TypeManager typeManager) { + this.typeManager = typeManager; + } + + public void setContentService(ContentService contentService) { + this.contentService = contentService; + } + + public void setPermissionService(PermissionService permissionService) { + this.permissionService = permissionService; + } + + public void setRepositoryInfoMap(RepositoryInfoMap repositoryInfoMap) { + this.repositoryInfoMap = repositoryInfoMap; + } + + public void setPrincipalService(PrincipalService principalService) { + this.principalService = principalService; + } +} diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java index 2079f35e..e16e821f 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java @@ -1,428 +1,440 @@ -/******************************************************************************* - * Copyright (c) 2013 aegif. - * - * This file is part of NemakiWare. - * - * NemakiWare 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 3 of the License, or - * (at your option) any later version. - * - * NemakiWare 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 NemakiWare. - * If not, see . - * - * Contributors: - * linzhixing(https://github.com/linzhixing) - initial API and implementation - ******************************************************************************/ -package jp.aegif.nemaki.cmis.aspect.impl; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import jp.aegif.nemaki.businesslogic.ContentService; -import jp.aegif.nemaki.businesslogic.PrincipalService; -import jp.aegif.nemaki.cmis.aspect.PermissionService; -import jp.aegif.nemaki.cmis.aspect.type.TypeManager; -import jp.aegif.nemaki.cmis.factory.info.RepositoryInfo; -import jp.aegif.nemaki.cmis.factory.info.RepositoryInfoMap; -import jp.aegif.nemaki.model.Ace; -import jp.aegif.nemaki.model.Acl; -import jp.aegif.nemaki.model.Content; -import jp.aegif.nemaki.model.Document; -import jp.aegif.nemaki.model.Relationship; -import jp.aegif.nemaki.model.VersionSeries; -import jp.aegif.nemaki.util.constant.CallContextKey; -import jp.aegif.nemaki.util.constant.CmisPermission; - -import org.apache.chemistry.opencmis.commons.data.AllowableActions; -import org.apache.chemistry.opencmis.commons.data.ObjectData; -import org.apache.chemistry.opencmis.commons.data.PermissionMapping; -import org.apache.chemistry.opencmis.commons.enums.Action; -import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; -import org.apache.chemistry.opencmis.commons.server.CallContext; -import org.apache.chemistry.opencmis.server.impl.CallContextImpl; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Permission Service implementation. - * - */ -public class PermissionServiceImpl implements PermissionService { - - private static final Log log = LogFactory - .getLog(PermissionServiceImpl.class); - - private PrincipalService principalService; - private ContentService contentService; - private TypeManager typeManager; - private RepositoryInfoMap repositoryInfoMap; - - - // ////////////////////////////////////////////////////////////////////////// - // Permission Check called from each CMIS method - // ////////////////////////////////////////////////////////////////////////// - @Override - public boolean checkPermission(CallContext callContext, Action action, ObjectData objectData){ - AllowableActions _actions = objectData.getAllowableActions(); - if(_actions == null){ - return false; - }else{ - Set actions = _actions.getAllowableActions(); - if(CollectionUtils.isEmpty(actions)){ - return false; - }else{ - return actions.contains(action); - } - } - } - - /** - * - */ - //TODO Merge arguments(acl, content) - //FIXME Refactor duplicate isAllowableBaseType - @Override - public Boolean checkPermission(CallContext callContext, String repositoryId, String key, - Acl acl, String baseType, Content content) { - - //All permission checks must go through baseType check - if(!isAllowableBaseType(key, baseType, content, repositoryId)) return false; - - // Admin always pass a permission check - CallContextImpl cci = (CallContextImpl) callContext; - Boolean _isAdmin = (Boolean) cci.get(CallContextKey.IS_ADMIN); - boolean isAdmin = (_isAdmin == null) ? false : _isAdmin; - if (isAdmin) return true; - - //PWC doesn't accept any actions from a non-owner user - //TODO admin can manipulate PWC even when it is checked out ? - if(content.isDocument()){ - Document document = (Document)content; - if(document.isPrivateWorkingCopy()){ - VersionSeries vs = contentService.getVersionSeries(repositoryId, document); - if(!callContext.getUsername().equals(vs.getVersionSeriesCheckedOutBy())){ - return false; - } - } - } - - // Relation has no ACL stored in DB. - // Though some actions are defined in the specs, - // Some other direct actions is needed to be set here. - if(content.isRelationship()){ - Relationship relationship = (Relationship)content; - return checkRelationshipPermission(callContext, repositoryId, key, relationship); - } - - // Void Acl fails(but Admin can do an action) - if (acl == null) - return false; - - // Even if a user has multiple ACEs, the permissions is pushed into - // Set and remain unique. - // Get ACL for the current user - String userName = callContext.getUsername(); - List aces = acl.getAllAces(); - Set userPermissions = new HashSet(); - Set groups = principalService.getGroupIdsContainingUser(repositoryId, userName); - for (Ace ace : aces) { - // Filter ace which has not permissions - if (ace.getPermissions() == null) - continue; - - // Add user permissions - if (ace.getPrincipalId().equals(userName)) { - userPermissions.addAll(ace.getPermissions()); - } - // Add inherited permissions which user inherits - if(CollectionUtils.isNotEmpty(groups) && groups.contains(ace.getPrincipalId())){ - userPermissions.addAll(ace.getPermissions()); - } - } - - // Check mapping between the user and the content - return checkCalculatedPermissions(repositoryId, key, userPermissions); - } - - /** - * - * @param repositoryId TODO - * @param key - * @param userPermissions - * @return - */ - private boolean checkCalculatedPermissions(String repositoryId, String key, Set userPermissions) { - Map table = repositoryInfoMap.get(repositoryId).getAclCapabilities().getPermissionMapping(); - List actionPermissions = table.get(key).getPermissions(); - - for (String up : userPermissions) { - if (actionPermissions.contains(up) || - CmisPermission.ALL.equals(up)) { - //If any one of user permissions is contained, action is allowed. - return true; - } - } - return false; - } - - /** - * TODO In the future, enable different configuration for Read/Update/Delete. - * @param callContext - * @param repositoryId TODO - * @param key - * @param relationship - * @return - */ - private Boolean checkRelationshipPermission(CallContext callContext, String repositoryId, String key, Relationship relationship){ - Content source = contentService.getRelationship(repositoryId, relationship.getSourceId()); - Content target = contentService.getRelationship(repositoryId, relationship.getTargetId()); - - if(source == null || target == null){ - log.warn("[objectId=" + relationship.getId() + "]Source or target of this relationship is missing"); - return false; - } - - //Read action when a relationship is specified directly - if(PermissionMapping.CAN_GET_PROPERTIES_OBJECT.equals(key)){ - boolean readSource = - checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, source), source.getType(), source); - boolean readTarget = - checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, target), target.getType(), target); - return readSource | readTarget; - } - - //Update action - if(PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT.equals(key)){ - boolean updateSource = - checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, source), source.getType(), source); - boolean updateTarget = - checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, target), target.getType(), target); - return updateSource | updateTarget; - } - - //Delete action - if(PermissionMapping.CAN_DELETE_OBJECT.equals(key)){ - boolean deleteSource = - checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, source), source.getType(), source); - boolean deleteTarget = - checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, target), target.getType(), target); - return deleteSource | deleteTarget; - } - - return false; - } - - private Boolean isAllowableBaseType(String key, String baseType, Content content, String repositoryId) { - // NavigationServices - if (PermissionMapping.CAN_GET_DESCENDENTS_FOLDER.equals(key)) - return BaseTypeId.CMIS_FOLDER.value().equals(baseType); - if (PermissionMapping.CAN_GET_CHILDREN_FOLDER.equals(key)) - return BaseTypeId.CMIS_FOLDER.value().equals(baseType); - if (PermissionMapping.CAN_GET_FOLDER_PARENT_OBJECT.equals(key)) - if(contentService.isRoot(repositoryId, content)){ - return false; - }else{ - return BaseTypeId.CMIS_FOLDER.value().equals(baseType); - } - if (PermissionMapping.CAN_GET_PARENTS_FOLDER.equals(key)) - if(contentService.isRoot(repositoryId, content)){ - return false; - }else{ - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM.value().equals(baseType)); - } - - // Object Services - if (PermissionMapping.CAN_CREATE_DOCUMENT_FOLDER.equals(key)) - return BaseTypeId.CMIS_FOLDER.value().equals(baseType); - if (PermissionMapping.CAN_CREATE_FOLDER_FOLDER.equals(key)) - return BaseTypeId.CMIS_FOLDER.value().equals(baseType); - if (PermissionMapping.CAN_CREATE_POLICY_FOLDER.equals(key)) - return BaseTypeId.CMIS_FOLDER.value().equals(baseType); - if (PermissionMapping.CAN_CREATE_RELATIONSHIP_SOURCE.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM - .equals(baseType)); - if (PermissionMapping.CAN_CREATE_RELATIONSHIP_TARGET.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM - .value().equals(baseType)); - if (PermissionMapping.CAN_GET_PROPERTIES_OBJECT.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM - .value().equals(baseType)); - if (PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM - .value().equals(baseType)); - if (PermissionMapping.CAN_MOVE_OBJECT.equals(key)) - if(contentService.isRoot(repositoryId, content)){ - return false; - }else{ - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM - .value().equals(baseType)); - } - if (PermissionMapping.CAN_MOVE_TARGET.equals(key)) - return BaseTypeId.CMIS_FOLDER.value().equals(baseType); - if (PermissionMapping.CAN_MOVE_SOURCE.equals(key)) - return BaseTypeId.CMIS_FOLDER.value().equals(baseType); - if (PermissionMapping.CAN_DELETE_OBJECT.equals(key)) - if(contentService.isRoot(repositoryId, content)){ - return false; - }else{ - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM - .value().equals(baseType)); - } - if (PermissionMapping.CAN_VIEW_CONTENT_OBJECT.equals(key)) - return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); - if (PermissionMapping.CAN_SET_CONTENT_DOCUMENT.equals(key)) - return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); - if (PermissionMapping.CAN_DELETE_CONTENT_DOCUMENT.equals(key)) - return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); - if (PermissionMapping.CAN_DELETE_TREE_FOLDER.equals(key)) - return BaseTypeId.CMIS_FOLDER.value().equals(baseType); - // Filing Services - if (PermissionMapping.CAN_ADD_TO_FOLDER_OBJECT.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM - .value().equals(baseType)); - if (PermissionMapping.CAN_ADD_TO_FOLDER_OBJECT.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM - .value().equals(baseType)); - if (PermissionMapping.CAN_REMOVE_FROM_FOLDER_OBJECT.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM - .value().equals(baseType)); - if (PermissionMapping.CAN_REMOVE_FROM_FOLDER_FOLDER.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) || BaseTypeId.CMIS_POLICY - .value().equals(baseType)); - // Versioning Services - if (PermissionMapping.CAN_CHECKOUT_DOCUMENT.equals(key)) - return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); - if (PermissionMapping.CAN_CANCEL_CHECKOUT_DOCUMENT.equals(key)) - return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); - if (PermissionMapping.CAN_CHECKIN_DOCUMENT.equals(key)) - return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); - if (PermissionMapping.CAN_GET_ALL_VERSIONS_VERSION_SERIES.equals(key)) - return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); - // Relationship Services - if (PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM - .value().equals(baseType)); - // Policy Services - if (PermissionMapping.CAN_ADD_POLICY_OBJECT.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM - .value().equals(baseType)); - if (PermissionMapping.CAN_ADD_POLICY_POLICY.equals(key)) - return BaseTypeId.CMIS_POLICY.value().equals(baseType); - if (PermissionMapping.CAN_REMOVE_POLICY_OBJECT.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM.value() - .equals(baseType)); - if (PermissionMapping.CAN_REMOVE_POLICY_POLICY.equals(key)) - return BaseTypeId.CMIS_POLICY.value().equals(baseType); - if (PermissionMapping.CAN_GET_APPLIED_POLICIES_OBJECT.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM.value() - .equals(baseType)); - // ACL Services - if (PermissionMapping.CAN_GET_ACL_OBJECT.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM.value() - .equals(baseType)); - if (PermissionMapping.CAN_APPLY_ACL_OBJECT.equals(key)) - return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) - || BaseTypeId.CMIS_FOLDER.value().equals(baseType) - || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) - || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM.value() - .equals(baseType)); - - return false; - } - - /** - * Filtering check to a list of contents based on the permission - */ - @Override - public List getFiltered(CallContext callContext, - String repositoryId, List contents) { - List result = new ArrayList(); - - // Validation - // TODO refine the logic - if (CollectionUtils.isEmpty(contents)){ - return null; - } - - // Filtering - for (T _content : contents) { - Content content = (Content) _content; - Acl acl = contentService.calculateAcl(repositoryId, content); - - Boolean filtered = checkPermission(callContext, - repositoryId, PermissionMapping.CAN_GET_PROPERTIES_OBJECT, acl, content.getType(), content); - if (filtered) { - result.add(_content); - } - } - return result; - } - - public void setNemakiPermissions(List> nemakiPermissions) { - } - - public void setPrincipalService(PrincipalService principalService) { - this.principalService = principalService; - } - - public void setContentService(ContentService contentService) { - this.contentService = contentService; - } - - - public TypeManager getTypeManager() { - return typeManager; - } - - public void setTypeManager(TypeManager typeManager) { - this.typeManager = typeManager; - } - - public void setRepositoryInfoMap(RepositoryInfoMap repositoryInfoMap) { - this.repositoryInfoMap = repositoryInfoMap; - } - +/******************************************************************************* + * Copyright (c) 2013 aegif. + * + * This file is part of NemakiWare. + * + * NemakiWare 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 3 of the License, or + * (at your option) any later version. + * + * NemakiWare 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 NemakiWare. + * If not, see . + * + * Contributors: + * linzhixing(https://github.com/linzhixing) - initial API and implementation + ******************************************************************************/ +package jp.aegif.nemaki.cmis.aspect.impl; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import jp.aegif.nemaki.businesslogic.ContentService; +import jp.aegif.nemaki.businesslogic.PrincipalService; +import jp.aegif.nemaki.cmis.aspect.PermissionService; +import jp.aegif.nemaki.cmis.aspect.type.TypeManager; +import jp.aegif.nemaki.cmis.factory.info.RepositoryInfo; +import jp.aegif.nemaki.cmis.factory.info.RepositoryInfoMap; +import jp.aegif.nemaki.model.Ace; +import jp.aegif.nemaki.model.Acl; +import jp.aegif.nemaki.model.Content; +import jp.aegif.nemaki.model.Document; +import jp.aegif.nemaki.model.Relationship; +import jp.aegif.nemaki.model.VersionSeries; +import jp.aegif.nemaki.util.constant.CallContextKey; +import jp.aegif.nemaki.util.constant.CmisPermission; + +import org.apache.chemistry.opencmis.commons.data.AllowableActions; +import org.apache.chemistry.opencmis.commons.data.ObjectData; +import org.apache.chemistry.opencmis.commons.data.PermissionMapping; +import org.apache.chemistry.opencmis.commons.enums.Action; +import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; +import org.apache.chemistry.opencmis.commons.server.CallContext; +import org.apache.chemistry.opencmis.server.impl.CallContextImpl; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.log4j.Logger; + +/** + * Permission Service implementation. + * + */ +public class PermissionServiceImpl implements PermissionService { + + private static final Log log = LogFactory + .getLog(PermissionServiceImpl.class); + + private PrincipalService principalService; + private ContentService contentService; + private TypeManager typeManager; + private RepositoryInfoMap repositoryInfoMap; + + + // ////////////////////////////////////////////////////////////////////////// + // Permission Check called from each CMIS method + // ////////////////////////////////////////////////////////////////////////// + @Override + public boolean checkPermission(CallContext callContext, Action action, ObjectData objectData){ + AllowableActions _actions = objectData.getAllowableActions(); + if(_actions == null){ + return false; + }else{ + Set actions = _actions.getAllowableActions(); + if(CollectionUtils.isEmpty(actions)){ + return false; + }else{ + return actions.contains(action); + } + } + } + + /** + * + */ + //TODO Merge arguments(acl, content) + //FIXME Refactor duplicate isAllowableBaseType + @Override + public Boolean checkPermission(CallContext callContext, String repositoryId, String key, + Acl acl, String baseType, Content content) { + + //All permission checks must go through baseType check + if(!isAllowableBaseType(key, baseType, content, repositoryId)) return false; + + // Admin always pass a permission check + CallContextImpl cci = (CallContextImpl) callContext; + Boolean _isAdmin = (Boolean) cci.get(CallContextKey.IS_ADMIN); + boolean isAdmin = (_isAdmin == null) ? false : _isAdmin; + log.debug(String.format("[%s][User:%s][Permission:true] is_admin? => %s", content.getName(), callContext.getUsername(), isAdmin)); + if (isAdmin) return true; + + //PWC doesn't accept any actions from a non-owner user + //TODO admin can manipulate PWC even when it is checked out ? + if(content.isDocument()){ + Document document = (Document)content; + if(document.isPrivateWorkingCopy()){ + VersionSeries vs = contentService.getVersionSeries(repositoryId, document); + if(!callContext.getUsername().equals(vs.getVersionSeriesCheckedOutBy())){ + log.debug(String.format("[%s][User:%s][Permission:false] PWS correct user => %s ", content.getName(),callContext.getUsername(), vs.getVersionSeriesCheckedOutBy())); + return false; + } + } + } + + // Relation has no ACL stored in DB. + // Though some actions are defined in the specs, + // Some other direct actions is needed to be set here. + if(content.isRelationship()){ + + + Relationship relationship = (Relationship)content; + boolean hasRelationshipPermission = checkRelationshipPermission(callContext, repositoryId, key, relationship); + log.debug(String.format("[%s][User:%s][Permission:%s] Is relationship. ", content.getName(), callContext.getUsername(),hasRelationshipPermission)); + return hasRelationshipPermission; + } + + // Void Acl fails(but Admin can do an action) + if (acl == null){ + log.debug(String.format("[%s][User:%s][Permission:false] No Acl! ", content.getName(), callContext.getUsername())); + return false; + } + + // Even if a user has multiple ACEs, the permissions is pushed into + // Set and remain unique. + // Get ACL for the current user + String userName = callContext.getUsername(); + List aces = acl.getAllAces(); + Set userPermissions = new HashSet(); + Set groups = principalService.getGroupIdsContainingUser(repositoryId, userName); + for (Ace ace : aces) { + // Filter ace which has not permissions + if (ace.getPermissions() == null) + continue; + + // Add user permissions + if (ace.getPrincipalId().equals(userName)) { + userPermissions.addAll(ace.getPermissions()); + } + // Add inherited permissions which user inherits + if(CollectionUtils.isNotEmpty(groups) && groups.contains(ace.getPrincipalId())){ + userPermissions.addAll(ace.getPermissions()); + } + } + + // Check mapping between the user and the content + boolean calcPermission = checkCalculatedPermissions(repositoryId, key, userPermissions); + log.debug(String.format("[%s][User:%s][Permission:%s] Check Mapping. ", content.getName(), callContext.getUsername(), calcPermission)); + return calcPermission; + } + + /** + * + * @param repositoryId TODO + * @param key + * @param userPermissions + * @return + */ + private boolean checkCalculatedPermissions(String repositoryId, String key, Set userPermissions) { + Map table = repositoryInfoMap.get(repositoryId).getAclCapabilities().getPermissionMapping(); + List actionPermissions = table.get(key).getPermissions(); + + for (String up : userPermissions) { + if (actionPermissions.contains(up) || + CmisPermission.ALL.equals(up)) { + //If any one of user permissions is contained, action is allowed. + + return true; + } + } + return false; + } + + /** + * TODO In the future, enable different configuration for Read/Update/Delete. + * @param callContext + * @param repositoryId TODO + * @param key + * @param relationship + * @return + */ + private Boolean checkRelationshipPermission(CallContext callContext, String repositoryId, String key, Relationship relationship){ + Content source = contentService.getRelationship(repositoryId, relationship.getSourceId()); + Content target = contentService.getRelationship(repositoryId, relationship.getTargetId()); + + if(source == null || target == null){ + log.warn("[objectId=" + relationship.getId() + "]Source or target of this relationship is missing"); + return false; + } + + //Read action when a relationship is specified directly + if(PermissionMapping.CAN_GET_PROPERTIES_OBJECT.equals(key)){ + boolean readSource = + checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, source), source.getType(), source); + boolean readTarget = + checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, target), target.getType(), target); + return readSource | readTarget; + } + + //Update action + if(PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT.equals(key)){ + boolean updateSource = + checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, source), source.getType(), source); + boolean updateTarget = + checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, target), target.getType(), target); + return updateSource | updateTarget; + } + + //Delete action + if(PermissionMapping.CAN_DELETE_OBJECT.equals(key)){ + boolean deleteSource = + checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, source), source.getType(), source); + boolean deleteTarget = + checkPermission(callContext, repositoryId, PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT, contentService.calculateAcl(repositoryId, target), target.getType(), target); + return deleteSource | deleteTarget; + } + + return false; + } + + private Boolean isAllowableBaseType(String key, String baseType, Content content, String repositoryId) { + // NavigationServices + if (PermissionMapping.CAN_GET_DESCENDENTS_FOLDER.equals(key)) + return BaseTypeId.CMIS_FOLDER.value().equals(baseType); + if (PermissionMapping.CAN_GET_CHILDREN_FOLDER.equals(key)) + return BaseTypeId.CMIS_FOLDER.value().equals(baseType); + if (PermissionMapping.CAN_GET_FOLDER_PARENT_OBJECT.equals(key)) + if(contentService.isRoot(repositoryId, content)){ + return false; + }else{ + return BaseTypeId.CMIS_FOLDER.value().equals(baseType); + } + if (PermissionMapping.CAN_GET_PARENTS_FOLDER.equals(key)) + if(contentService.isRoot(repositoryId, content)){ + return false; + }else{ + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM.value().equals(baseType)); + } + + // Object Services + if (PermissionMapping.CAN_CREATE_DOCUMENT_FOLDER.equals(key)) + return BaseTypeId.CMIS_FOLDER.value().equals(baseType); + if (PermissionMapping.CAN_CREATE_FOLDER_FOLDER.equals(key)) + return BaseTypeId.CMIS_FOLDER.value().equals(baseType); + if (PermissionMapping.CAN_CREATE_POLICY_FOLDER.equals(key)) + return BaseTypeId.CMIS_FOLDER.value().equals(baseType); + if (PermissionMapping.CAN_CREATE_RELATIONSHIP_SOURCE.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM + .equals(baseType)); + if (PermissionMapping.CAN_CREATE_RELATIONSHIP_TARGET.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM + .value().equals(baseType)); + if (PermissionMapping.CAN_GET_PROPERTIES_OBJECT.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM + .value().equals(baseType)); + if (PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM + .value().equals(baseType)); + if (PermissionMapping.CAN_MOVE_OBJECT.equals(key)) + if(contentService.isRoot(repositoryId, content)){ + return false; + }else{ + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM + .value().equals(baseType)); + } + if (PermissionMapping.CAN_MOVE_TARGET.equals(key)) + return BaseTypeId.CMIS_FOLDER.value().equals(baseType); + if (PermissionMapping.CAN_MOVE_SOURCE.equals(key)) + return BaseTypeId.CMIS_FOLDER.value().equals(baseType); + if (PermissionMapping.CAN_DELETE_OBJECT.equals(key)) + if(contentService.isRoot(repositoryId, content)){ + return false; + }else{ + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM + .value().equals(baseType)); + } + if (PermissionMapping.CAN_VIEW_CONTENT_OBJECT.equals(key)) + return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); + if (PermissionMapping.CAN_SET_CONTENT_DOCUMENT.equals(key)) + return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); + if (PermissionMapping.CAN_DELETE_CONTENT_DOCUMENT.equals(key)) + return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); + if (PermissionMapping.CAN_DELETE_TREE_FOLDER.equals(key)) + return BaseTypeId.CMIS_FOLDER.value().equals(baseType); + // Filing Services + if (PermissionMapping.CAN_ADD_TO_FOLDER_OBJECT.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM + .value().equals(baseType)); + if (PermissionMapping.CAN_ADD_TO_FOLDER_OBJECT.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM + .value().equals(baseType)); + if (PermissionMapping.CAN_REMOVE_FROM_FOLDER_OBJECT.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM + .value().equals(baseType)); + if (PermissionMapping.CAN_REMOVE_FROM_FOLDER_FOLDER.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) || BaseTypeId.CMIS_POLICY + .value().equals(baseType)); + // Versioning Services + if (PermissionMapping.CAN_CHECKOUT_DOCUMENT.equals(key)) + return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); + if (PermissionMapping.CAN_CANCEL_CHECKOUT_DOCUMENT.equals(key)) + return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); + if (PermissionMapping.CAN_CHECKIN_DOCUMENT.equals(key)) + return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); + if (PermissionMapping.CAN_GET_ALL_VERSIONS_VERSION_SERIES.equals(key)) + return BaseTypeId.CMIS_DOCUMENT.value().equals(baseType); + // Relationship Services + if (PermissionMapping.CAN_GET_OBJECT_RELATIONSHIPS_OBJECT.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM + .value().equals(baseType)); + // Policy Services + if (PermissionMapping.CAN_ADD_POLICY_OBJECT.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM + .value().equals(baseType)); + if (PermissionMapping.CAN_ADD_POLICY_POLICY.equals(key)) + return BaseTypeId.CMIS_POLICY.value().equals(baseType); + if (PermissionMapping.CAN_REMOVE_POLICY_OBJECT.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM.value() + .equals(baseType)); + if (PermissionMapping.CAN_REMOVE_POLICY_POLICY.equals(key)) + return BaseTypeId.CMIS_POLICY.value().equals(baseType); + if (PermissionMapping.CAN_GET_APPLIED_POLICIES_OBJECT.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM.value() + .equals(baseType)); + // ACL Services + if (PermissionMapping.CAN_GET_ACL_OBJECT.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM.value() + .equals(baseType)); + if (PermissionMapping.CAN_APPLY_ACL_OBJECT.equals(key)) + return (BaseTypeId.CMIS_DOCUMENT.value().equals(baseType) + || BaseTypeId.CMIS_FOLDER.value().equals(baseType) + || BaseTypeId.CMIS_RELATIONSHIP.value().equals(baseType) + || BaseTypeId.CMIS_POLICY.value().equals(baseType) || BaseTypeId.CMIS_ITEM.value() + .equals(baseType)); + + return false; + } + + /** + * Filtering check to a list of contents based on the permission + */ + @Override + public List getFiltered(CallContext callContext, + String repositoryId, List contents) { + List result = new ArrayList(); + + // Validation + // TODO refine the logic + if (CollectionUtils.isEmpty(contents)){ + return null; + } + + // Filtering + for (T _content : contents) { + Content content = (Content) _content; + Acl acl = contentService.calculateAcl(repositoryId, content); + + Boolean filtered = checkPermission(callContext, + repositoryId, PermissionMapping.CAN_GET_PROPERTIES_OBJECT, acl, content.getType(), content); + if (filtered) { + result.add(_content); + } + } + return result; + } + + public void setNemakiPermissions(List> nemakiPermissions) { + } + + public void setPrincipalService(PrincipalService principalService) { + this.principalService = principalService; + } + + public void setContentService(ContentService contentService) { + this.contentService = contentService; + } + + + public TypeManager getTypeManager() { + return typeManager; + } + + public void setTypeManager(TypeManager typeManager) { + this.typeManager = typeManager; + } + + public void setRepositoryInfoMap(RepositoryInfoMap repositoryInfoMap) { + this.repositoryInfoMap = repositoryInfoMap; + } + } \ No newline at end of file From 9d3a2d3dca9dd81f9f25967c7dd4371c13e19fb1 Mon Sep 17 00:00:00 2001 From: git -v Date: Fri, 25 Dec 2015 17:07:25 +0900 Subject: [PATCH 08/20] Modify : Version no --- core/pom.xml | 2 +- solr/pom.xml | 2 +- ui/build.sbt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index da74bd86..ebd624fa 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -5,7 +5,7 @@ jp.aegif.nemaki core war - 2.3.6 + 2.3.7 core NemakiWare server https://github.com/NemakiWare/NemakiWare diff --git a/solr/pom.xml b/solr/pom.xml index 53e1a8ab..187e76ab 100644 --- a/solr/pom.xml +++ b/solr/pom.xml @@ -5,7 +5,7 @@ jp.aegif.nemaki solr war - 2.3.6 + 2.3.7 solr Solr customized for Nemaki https://github.com/NemakiWare/NemakiWare diff --git a/ui/build.sbt b/ui/build.sbt index ca6caa52..3542bb33 100644 --- a/ui/build.sbt +++ b/ui/build.sbt @@ -2,7 +2,7 @@ import com.github.play2war.plugin._ name := """ui""" -version := "2.3.6" +version := "2.3.7" lazy val root = (project in file(".")).enablePlugins(PlayJava) From eaf16e8328dfe446d7abfd92b0db55133efca5b5 Mon Sep 17 00:00:00 2001 From: git -v Date: Tue, 29 Dec 2015 14:15:36 +0900 Subject: [PATCH 09/20] Add : Amazon Bean Stalk config --- setup/development/aws/.ebextensions/nemaki_ebs.config | 0 setup/development/build.bat | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 setup/development/aws/.ebextensions/nemaki_ebs.config diff --git a/setup/development/aws/.ebextensions/nemaki_ebs.config b/setup/development/aws/.ebextensions/nemaki_ebs.config new file mode 100644 index 00000000..e69de29b diff --git a/setup/development/build.bat b/setup/development/build.bat index 1c0af342..d74f0a37 100644 --- a/setup/development/build.bat +++ b/setup/development/build.bat @@ -22,7 +22,7 @@ if not exist "%OUTPUT_WAR_DIR%" ( rem for aws beanstalk if not exist "%OUTPUT_WAR_DIR%.ebextensions" ( - mkdir "%OUTPUT_WAR_DIR%.ebextensions" + xcopy "%BAT_DIR%.ebextensions" "%OUTPUT_WAR_DIR%" /Y ) From 4c87b2423f2081280bc06098f36c7a79470d6291 Mon Sep 17 00:00:00 2001 From: git -v Date: Tue, 5 Jan 2016 10:31:35 +0900 Subject: [PATCH 10/20] Modify : modify logger --- .../impl/ContentServiceImpl.java | 27 +++-- .../cmis/aspect/impl/CompileServiceImpl.java | 110 +++++++++--------- .../aspect/impl/ExceptionServiceImpl.java | 2 +- .../aspect/impl/PermissionServiceImpl.java | 19 ++- .../cmis/aspect/query/solr/SolrUtil.java | 2 +- .../auth/impl/AuthenticationServiceImpl.java | 4 +- .../cmis/service/impl/ObjectServiceImpl.java | 52 +++++---- .../impl/couch/PrincipalDaoServiceImpl.java | 4 +- .../main/java/jp/aegif/nemaki/model/User.java | 2 +- .../nemaki/rest/AuthenticationFilter.java | 32 ++--- .../util/spring/aspect/DefaultLogger.java | 14 +-- .../webapp/WEB-INF/classes/log4j.tomcat.xml | 2 +- .../src/main/webapp/WEB-INF/classes/log4j.xml | 32 ++--- .../WEB-INF/classes/nemakiware.properties | 6 +- 14 files changed, 157 insertions(+), 151 deletions(-) diff --git a/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java index d7658ab8..fa805e24 100644 --- a/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java @@ -106,7 +106,7 @@ public class ContentServiceImpl implements ContentService { private PropertyManager propertyManager; private SolrUtil solrUtil; - private static final Log logger = LogFactory.getLog(ContentServiceImpl.class); + private static final Log log = LogFactory.getLog(ContentServiceImpl.class); private final static String PATH_SEPARATOR = "/"; // /////////////////////////////////////// @@ -171,7 +171,7 @@ public Content getContentByPath(String repositoryId, String path) { for (int i = 1; i < splittedPath.size(); i++) { String leafName = splittedPath.get(i); if (content == null) { - logger.warn("Leaf node '" + leafName + "' in path '" + path + "' is not found."); + log.warn("Leaf node '" + leafName + "' in path '" + path + "' is not found."); return null; } else { Content child = contentDaoService.getChildByName(repositoryId, content.getId(), leafName); @@ -437,7 +437,7 @@ public Document createDocument(CallContext callContext, String repositoryId, Pro } } catch (Exception ex) { // not stop follow sequence - logger.error(ex); + log.error(ex); } } } @@ -447,6 +447,7 @@ public Document createDocument(CallContext callContext, String repositoryId, Pro // Create Document document = contentDaoService.create(repositoryId, d); + log.debug(String.format("[%s][%s][%s]Create entry on couchdb successfully.",repositoryId, document.getId(), contentStream.getFileName())); // Update versionSeriesId#versionSeriesCheckedOutId after creating a PWC if (versioningState == VersioningState.CHECKEDOUT) { @@ -457,7 +458,11 @@ public Document createDocument(CallContext callContext, String repositoryId, Pro writeChangeEvent(callContext, repositoryId, document, ChangeType.CREATED); // Call Solr indexing(optional) - solrUtil.callSolrIndexing(repositoryId); + try{ + solrUtil.callSolrIndexing(repositoryId); + }catch(Exception ex){ + log.error(String.format("[%s][%s][%s]Solr indexing falure : %s",repositoryId, document.getId(), contentStream.getFileName(), ex)); + } return document; } @@ -1301,7 +1306,7 @@ public List deleteTree(CallContext callContext, String repositoryId, Str failureIds.add(child.getId()); continue; } else { - logger.error("", e); + log.error("", e); } } } @@ -1314,7 +1319,7 @@ public List deleteTree(CallContext callContext, String repositoryId, Str if (continueOnFailure) { failureIds.add(folderId); } else { - logger.error("", e); + log.error("", e); } } @@ -1637,13 +1642,13 @@ public Archive createAttachmentArchive(CallContext callContext, String repositor public void restoreArchive(String repositoryId, String archiveId) { Archive archive = contentDaoService.getArchive(repositoryId, archiveId); if (archive == null) { - logger.error("Archive does not exist!"); + log.error("Archive does not exist!"); return; } // Check whether the destination does still extist. if (!restorationTargetExists(repositoryId, archive)) { - logger.error("The destination of the restoration doesn't exist"); + log.error("The destination of the restoration doesn't exist"); return; } @@ -1658,9 +1663,9 @@ public void restoreArchive(String repositoryId, String archiveId) { Document restored = restoreDocument(repositoryId, archive); writeChangeEvent(dummyContext, repositoryId, restored, ChangeType.CREATED); } else if (archive.isAttachment()) { - logger.error("Attachment can't be restored alone"); + log.error("Attachment can't be restored alone"); } else { - logger.error("Only document or folder is supported for restoration"); + log.error("Only document or folder is supported for restoration"); } // Call Solr indexing(optional) @@ -1683,7 +1688,7 @@ private Document restoreDocument(String repositoryId, Archive archive) { contentDaoService.deleteArchive(repositoryId, attachmentArchive.getId()); } } catch (Exception e) { - logger.error("fail to restore a document", e); + log.error("fail to restore a document", e); } return getDocument(repositoryId, archive.getOriginalId()); diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/CompileServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/CompileServiceImpl.java index dd0a06f2..5148fb1f 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/CompileServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/CompileServiceImpl.java @@ -122,7 +122,7 @@ public class CompileServiceImpl implements CompileService { private NemakiCachePool nemakiCachePool; private boolean includeRelationshipsEnabled = true; - + /** * Builds a CMIS ObjectData from the given CouchDB content. */ @@ -131,28 +131,28 @@ public ObjectData compileObjectData(CallContext callContext, String repositoryId Content content, String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, Boolean includeAcl) { - + ObjectDataImpl _result = new ObjectDataImpl(); - + Element v = nemakiCachePool.get(repositoryId).getObjectDataCache().get(content.getId()); if(v == null){ _result = compileObjectDataWithFullAttributes(callContext, repositoryId, content); }else{ _result = (ObjectDataImpl)v.getObjectValue(); } - + ObjectData result = filterObjectData(repositoryId, _result, filter, includeAllowableActions, includeRelationships, renditionFilter, includeAcl); - + return result; } - + private ObjectDataImpl compileObjectDataWithFullAttributes(CallContext callContext, String repositoryId, Content content){ ObjectDataImpl result = new ObjectDataImpl(); - + //Filter(any property filter MUST be done here PropertiesImpl properties = compileProperties(callContext, repositoryId, content); result.setProperties(properties); - + // Set Allowable actions result.setAllowableActions(compileAllowableActions(callContext, repositoryId, content)); @@ -160,64 +160,64 @@ private ObjectDataImpl compileObjectDataWithFullAttributes(CallContext callConte Acl acl = contentService.calculateAcl(repositoryId, content); result.setIsExactAcl(true); result.setAcl(compileAcl(acl, content.isAclInherited(), false)); - + //Set Relationship(BOTH) if (!content.isRelationship()) { if(includeRelationshipsEnabled){ result.setRelationships(compileRelationships(callContext, repositoryId, content, IncludeRelationships.BOTH)); } } - + // Set Renditions if (content.isDocument()){ result.setRenditions(compileRenditions(callContext, repositoryId, content)); - } - + } + nemakiCachePool.get(repositoryId).getObjectDataCache().put(new Element(content.getId(), result)); - + return result; } - + private ObjectData filterObjectData(String repositoryId, ObjectData fullObjectData, String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, String renditionFilter, Boolean includeAcl){ - + //Deep copy ObjectData //Shallow copy will cause a destructive effect after filtering some attributes Cloner cloner=new Cloner(); ObjectDataImpl result = DataUtil.convertObjectDataImpl(cloner.deepClone(fullObjectData)); - + Properties filteredProperties = filterProperties(result.getProperties(), splitFilter(filter)); result.setProperties(filteredProperties); - + // Filter Allowable actions Boolean iaa = includeAllowableActions == null ? false: includeAllowableActions.booleanValue(); if (!iaa) { result.setAllowableActions(null); } - + // Filter Acl Boolean iacl = includeAcl == null ? false : includeAcl.booleanValue(); if (!iacl) { result.setAcl(null); } - + // Filter Relationships IncludeRelationships irl = includeRelationships == null ? IncludeRelationships.SOURCE : includeRelationships; if (fullObjectData.getBaseTypeId() == BaseTypeId.CMIS_RELATIONSHIP) { result.setRelationships(filterRelationships(result.getId(), result.getRelationships(), irl)); } - + // Filter Renditions if (fullObjectData.getBaseTypeId() == BaseTypeId.CMIS_DOCUMENT && repositoryInfoMap.get(repositoryId).getCapabilities().getRenditionsCapability() == CapabilityRenditions.NONE) { result.setRenditions(null); } - + return result; } - + private ObjectData filterObjectDataInList(CallContext callContext, String repositoryId, ObjectData fullObjectData, String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships, @@ -229,10 +229,10 @@ private ObjectData filterObjectDataInList(CallContext callContext, String reposi return null; } } - + private Properties filterProperties(Properties properties, Set filter){ PropertiesImpl result = new PropertiesImpl(); - + //null filter as NO FILTER: do nothing if(filter == null){ return properties; @@ -246,7 +246,7 @@ private Properties filterProperties(Properties properties, Set filter){ } return result; } - + private List filterRelationships(String objectId, List bothRelationships, IncludeRelationships includeRelationships){ String propertyId; switch(includeRelationships){ @@ -268,13 +268,13 @@ private List filterRelationships(String objectId, List b filtered.add(rel); } } - + return filtered; }else{ return null; } } - + @Override public ObjectList compileObjectDataList(CallContext callContext, String repositoryId, List contents, String filter, @@ -283,7 +283,7 @@ public ObjectList compileObjectDataList(CallContext callContext, BigInteger skipCount, boolean folderOnly) { ObjectListImpl list = new ObjectListImpl(); list.setObjects(new ArrayList()); - + //Return empty result when no children exist if (CollectionUtils.isEmpty(contents)) { list.setNumItems(BigInteger.ZERO); @@ -312,13 +312,13 @@ public ObjectList compileObjectDataList(CallContext callContext, if (ods.size() >= max) { break; } - + Content _c = (Content) t; //Filter by folderOnly if(folderOnly && !_c.isFolder()){ continue; } - + //Convert content class Content c = null; if(_c.isFolder()){ @@ -332,7 +332,7 @@ public ObjectList compileObjectDataList(CallContext callContext, }else if(_c.isItem()){ c = (Item)t; } - + //Get each ObjectData ObjectData _od; Element v = nemakiCachePool.get(repositoryId).getObjectDataCache().get(c.getId()); @@ -341,14 +341,14 @@ public ObjectList compileObjectDataList(CallContext callContext, }else{ _od = (ObjectDataImpl)v.getObjectValue(); } - + ObjectData od = filterObjectDataInList(callContext, repositoryId, _od, filter, includeAllowableActions, includeRelationships, renditionFilter, includeAcl); if(od != null){ ods.add(od); } } list.setObjects(ods); - + //Set list meta data if(CollectionUtils.isEmpty(list.getObjects())){ return list; @@ -358,7 +358,7 @@ public ObjectList compileObjectDataList(CallContext callContext, list.setHasMoreItems(true); } } - + return list; } @@ -495,8 +495,8 @@ public AllowableActions compileAllowableActions(CallContext callContext, Document d = (Document)content; versionSeries = contentService.getVersionSeries(repositoryId, d); } - - + + for (Entry mappingEntry : permissionMap .entrySet()) { String key = mappingEntry.getValue().getKey(); @@ -544,7 +544,7 @@ public AllowableActions compileAllowableActions(CallContext callContext, private boolean isAllowableActionForVersionableDocument( CallContext callContext, String permissionMappingKey, Document document, VersionSeries versionSeries, DocumentTypeDefinition dtdf) { - + //Versioning action(checkOut / checkIn) if (permissionMappingKey .equals(PermissionMapping.CAN_CHECKOUT_DOCUMENT)) { @@ -556,8 +556,8 @@ private boolean isAllowableActionForVersionableDocument( .equals(PermissionMapping.CAN_CANCEL_CHECKOUT_DOCUMENT)) { return dtdf.isVersionable() && versionSeries.isVersionSeriesCheckedOut() && document.isPrivateWorkingCopy(); } - - + + //Lock as an effect of checkOut if(dtdf.isVersionable()){ if(isLockableAction(permissionMappingKey)){ @@ -725,7 +725,7 @@ private List compileRenditions(CallContext callContext, public PropertiesImpl compileProperties(CallContext callContext, String repositoryId, Content content) { TypeDefinitionContainer tdfc = typeManager.getTypeById(repositoryId, content.getObjectType()); TypeDefinition tdf = tdfc.getTypeDefinition(); - + PropertiesImpl properties = new PropertiesImpl(); if (content.isFolder()) { Folder folder = (Folder) content; @@ -754,7 +754,7 @@ public PropertiesImpl compileProperties(CallContext callContext, String reposito return properties; } - + private PropertiesImpl compileRootFolderProperties(String repositoryId, Folder folder, PropertiesImpl properties, TypeDefinition tdf) { setCmisBaseProperties(repositoryId, properties, tdf, folder); @@ -839,7 +839,7 @@ private void setCmisBaseProperties(String repositoryId, } addProperty(properties, tdf, PropertyIds.CHANGE_TOKEN, String.valueOf(content.getChangeToken())); - + // TODO If subType properties is not registered in DB, return void // properties via CMIS // SubType properties @@ -854,7 +854,7 @@ private void setCmisBaseProperties(String repositoryId, value); } } - + // Secondary properties setCmisSecondaryTypes(repositoryId, properties, content, tdf); } @@ -899,7 +899,7 @@ private void setCmisDocumentProperties(CallContext callContext, : document.isImmutable(); addProperty(properties, tdf, PropertyIds.IS_IMMUTABLE, isImmutable); - + DocumentTypeDefinition type = (DocumentTypeDefinition) typeManager .getTypeDefinition(repositoryId, tdf.getId()); if (type.isVersionable()) { @@ -923,7 +923,7 @@ private void setCmisDocumentProperties(CallContext callContext, if (vs.isVersionSeriesCheckedOut()) { String userId = callContext.getUsername(); String checkedOutBy = vs.getVersionSeriesCheckedOutBy(); - + if(userId.equals(checkedOutBy)){ addProperty(properties, tdf, PropertyIds.VERSION_SERIES_CHECKED_OUT_ID, vs.getVersionSeriesCheckedOutId()); @@ -935,7 +935,7 @@ private void setCmisDocumentProperties(CallContext callContext, addProperty(properties, tdf, PropertyIds.VERSION_SERIES_CHECKED_OUT_BY, checkedOutBy); } - + } else { addProperty(properties, tdf, PropertyIds.VERSION_SERIES_CHECKED_OUT_ID, null); @@ -974,23 +974,23 @@ private void setCmisAttachmentProperties(String repositoryId, String mimeType = null; String fileName = null; String streamId = null; - + //Check if ContentStream is attached DocumentTypeDefinition dtdf = (DocumentTypeDefinition)tdf; ContentStreamAllowed csa = dtdf.getContentStreamAllowed(); if(ContentStreamAllowed.REQUIRED == csa || ContentStreamAllowed.ALLOWED == csa && StringUtils.isNotBlank(document.getAttachmentNodeId())){ - + AttachmentNode attachment = contentService.getAttachmentRef(repositoryId, document .getAttachmentNodeId()); - + length = attachment.getLength(); mimeType = attachment.getMimeType(); //fileName = attachment.getName(); fileName = document.getName(); streamId = attachment.getId(); } - + //Add ContentStream properties to Document object addProperty(properties, dtdf, PropertyIds.CONTENT_STREAM_LENGTH, length); @@ -1105,7 +1105,7 @@ private boolean checkAddProperty(Properties properties, TypeDefinition tdf, Stri /** * Adds specified property in property set. - * + * * @param props * property set * @param tdf @@ -1122,8 +1122,8 @@ private void addProperty(PropertiesImpl props, TypeDefinition tdf, PropertyDefinition pdf = tdf.getPropertyDefinitions().get(id); if (!checkAddProperty(props, tdf, id)) return; - - + + switch (pdf.getPropertyType()) { case BOOLEAN: PropertyBooleanImpl propBoolean; @@ -1393,7 +1393,7 @@ public org.apache.chemistry.opencmis.commons.data.Acl compileAcl( return cmisAcl; } - + private void buildCmisAce(AccessControlListImpl cmisAcl, boolean direct, List aces, boolean onlyBasicPermissions){ if(CollectionUtils.isNotEmpty(aces)){ for (Ace ace : aces) { @@ -1425,7 +1425,7 @@ private void buildCmisAce(AccessControlListImpl cmisAcl, boolean direct, List %s", content.getName(), callContext.getUsername(), isAdmin)); - if (isAdmin) return true; + */ + + + if (u != null & u.isAdmin()) { + log.debug(String.format("[%s][User:%s][Permission:true] is_admin? => %s" , content.getName(), callContext.getUsername(), u.isAdmin())); + return true; + } //PWC doesn't accept any actions from a non-owner user //TODO admin can manipulate PWC even when it is checked out ? @@ -140,7 +149,7 @@ public Boolean checkPermission(CallContext callContext, String repositoryId, Str // Even if a user has multiple ACEs, the permissions is pushed into // Set and remain unique. // Get ACL for the current user - String userName = callContext.getUsername(); + List aces = acl.getAllAces(); Set userPermissions = new HashSet(); Set groups = principalService.getGroupIdsContainingUser(repositoryId, userName); diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/query/solr/SolrUtil.java b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/query/solr/SolrUtil.java index 4be20cfa..20be9354 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/query/solr/SolrUtil.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/query/solr/SolrUtil.java @@ -49,7 +49,7 @@ * */ public class SolrUtil { - private static final Log log = LogFactory.getFactory().getInstance(SortUtil.class); + private static final Log log = LogFactory.getLog(SortUtil.class); private final HashMap map; diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/factory/auth/impl/AuthenticationServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/cmis/factory/auth/impl/AuthenticationServiceImpl.java index aff35c40..ce976ee2 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/factory/auth/impl/AuthenticationServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/factory/auth/impl/AuthenticationServiceImpl.java @@ -145,10 +145,12 @@ private boolean loginWithBasicAuth(CallContext callContext) { User solrUser = principalService.getUserById(repositoryId, solrUserId); if (solrUser == null) { User newSolrUser = new User(solrUserId, solrUserId, "", "", "", BCrypt.hashpw(solrUserId, BCrypt.gensalt())); + newSolrUser.setAdmin(true); principalService.createUser(repositoryId, newSolrUser); } + return true; } @@ -181,7 +183,7 @@ private User getAuthenticatedUser(String repositoryId, String userName, String p // succeeded if (u != null) { if (AuthenticationUtil.passwordMatches(password, u.getPasswordHash())) { - log.debug("[" + userName + "]Authentication succeeded"); + log.debug(String.format( "[%s][%s]Get authenticated user successfully ! , Is admin? : %s", repositoryId, userName , u.isAdmin())); return u; } } diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java index 88638064..945308c3 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java @@ -80,7 +80,7 @@ public class ObjectServiceImpl implements ObjectService { private static final Log log = LogFactory .getLog(ObjectServiceImpl.class); - + private TypeManager typeManager; private ContentService contentService; private ExceptionService exceptionService; @@ -202,9 +202,9 @@ private ContentStream getRenditionStream(String repositoryId, Content content, S .constraint(content.getId(), "getRenditionStream cannnot be invoked to other than document or folder type."); } - + exceptionService.constraintRenditionStreamDownload(content, streamId); - + Rendition rendition = contentService.getRendition(repositoryId, streamId); BigInteger length = BigInteger.valueOf(rendition.getLength()); @@ -214,7 +214,7 @@ private ContentStream getRenditionStream(String repositoryId, Content content, S return cs; } - + @Override public List getRenditions(CallContext callContext, String repositoryId, String objectId, String renditionFilter, @@ -287,9 +287,13 @@ public ObjectData create(CallContext callContext, String repositoryId, "Cannot create object of type '" + typeId + "'!"); } - return compileService.compileObjectData(callContext, + log.debug(String.format("[%s][%s][%s]Creating object data by compileService ...",repositoryId, objectId, contentStream.getFileName())); + ObjectData object = compileService.compileObjectData(callContext, repositoryId, contentService.getContent(repositoryId, objectId), null, false, IncludeRelationships.NONE, null, false); + log.debug(String.format("[%s][%s][%s]Create object data by compileService successfully.",repositoryId, objectId, contentStream.getFileName())); + + return object; } @Override @@ -463,8 +467,8 @@ public void setContentStream(CallContext callContext, // ////////////////// // Body of the method // ////////////////// - String oldId = objectId.getValue(); - + String oldId = objectId.getValue(); + // TODO Externalize versioningState if(doc.isPrivateWorkingCopy()){ Document result = contentService.replacePwc(callContext, repositoryId, @@ -475,7 +479,7 @@ public void setContentStream(CallContext callContext, doc, contentStream); objectId.setValue(result.getId()); } - + nemakiCachePool.get(repositoryId).removeCmisCache(oldId); } @@ -492,12 +496,12 @@ public void deleteContentStream(CallContext callContext, exceptionService.objectNotFound(DomainType.OBJECT, document, document.getId()); exceptionService.constraintContentStreamRequired(repositoryId, document); - + // ////////////////// // Body of the method // ////////////////// contentService.deleteContentStream(callContext, repositoryId, objectId); - + nemakiCachePool.get(repositoryId).removeCmisCache(objectId.getValue()); } @@ -534,7 +538,7 @@ public void appendContentStream(CallContext callContext, // ////////////////// contentService.appendAttachment(callContext, repositoryId, objectId, changeToken, contentStream, isLastChunk, extension); - + nemakiCachePool.get(repositoryId).removeCmisCache(objectId.getValue()); } @@ -592,7 +596,7 @@ public String createRelationship(CallContext callContext, removeAces, extension); nemakiCachePool.get(repositoryId).removeCmisCache(relationship.getSourceId()); nemakiCachePool.get(repositoryId).removeCmisCache(relationship.getTargetId()); - + return relationship.getId(); } @@ -680,9 +684,9 @@ public void updateProperties(CallContext callContext, // Body of the method // ////////////////// String id = objectId.getValue(); - + contentService.updateProperties(callContext, repositoryId, properties, content); - + nemakiCachePool.get(repositoryId).removeCmisCache(id); } @@ -709,8 +713,8 @@ private Content checkExceptionBeforeUpdateProperties( exceptionService.permissionDenied(callContext, repositoryId, PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT, content); exceptionService.updateConflict(content, changeToken); - - + + TypeDefinition tdf = typeManager.getTypeDefinition(repositoryId, content); exceptionService.constraintPropertyValue(repositoryId, tdf, @@ -793,7 +797,7 @@ public void moveObject(CallContext callContext, String repositoryId, // Body of the method // ////////////////// contentService.move(repositoryId, content, target); - + nemakiCachePool.get(repositoryId).removeCmisCache(content.getId()); } @@ -823,14 +827,14 @@ private void deleteObjectInternal(CallContext callContext, String repositoryId, "deleteObject method is invoked on a folder containing objects."); } contentService.delete(callContext, repositoryId, objectId, deleteWithParent); - + } else { contentService.delete(callContext, repositoryId, objectId, deleteWithParent); } nemakiCachePool.get(repositoryId).removeCmisCache(content.getId()); } - + @Override public void deleteObject(CallContext callContext, String repositoryId, String objectId, Boolean allVersions) { @@ -862,7 +866,7 @@ public FailedToDeleteData deleteTree(CallContext callContext, // ////////////////// // Delete descendants List failureIds = new ArrayList(); - + List children = contentService.getChildren(repositoryId, folderId); if (!CollectionUtils.isEmpty(children)) { for (Content child : children) { @@ -876,7 +880,7 @@ public FailedToDeleteData deleteTree(CallContext callContext, } catch (Exception e) { StringBuilder sb = new StringBuilder(); sb.append("objectId:").append(child.getId()).append(" failed to be deleted."); - + if (continueOnFailure) { failureIds.add(child.getId()); log.warn(sb.toString(), e); @@ -894,7 +898,7 @@ public FailedToDeleteData deleteTree(CallContext callContext, } catch (Exception e) { StringBuilder sb = new StringBuilder(); sb.append("objectId:").append(folderId).append(" failed to be deleted."); - + if (continueOnFailure) { failureIds.add(folderId); log.warn(sb.toString(), e); @@ -902,7 +906,7 @@ public FailedToDeleteData deleteTree(CallContext callContext, log.error(sb.toString(), e); } } - + /*failureIds = contentService.deleteTree(callContext, folderId, allVersions, continueOnFailure, false);*/ solrUtil.callSolrIndexing(repositoryId); @@ -910,7 +914,7 @@ public FailedToDeleteData deleteTree(CallContext callContext, // Check FailedToDeleteData // FIXME Consider orphans that was failed to be deleted FailedToDeleteDataImpl fdd = new FailedToDeleteDataImpl(); - + if (CollectionUtils.isNotEmpty(failureIds)) { fdd.setIds(failureIds); } else { diff --git a/core/src/main/java/jp/aegif/nemaki/dao/impl/couch/PrincipalDaoServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/dao/impl/couch/PrincipalDaoServiceImpl.java index 145196ac..8c661af5 100644 --- a/core/src/main/java/jp/aegif/nemaki/dao/impl/couch/PrincipalDaoServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/dao/impl/couch/PrincipalDaoServiceImpl.java @@ -35,6 +35,7 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.log4j.Logger; import org.ektorp.ViewQuery; import org.springframework.stereotype.Component; @@ -48,8 +49,7 @@ public class PrincipalDaoServiceImpl implements PrincipalDaoService { private ConnectorPool connectorPool; - private static final Log logger = LogFactory - .getLog(PrincipalDaoServiceImpl.class); + private static final Log log = LogFactory.getLog(PrincipalDaoServiceImpl.class); private static final String DESIGN_DOCUMENT = "_design/_repo"; public PrincipalDaoServiceImpl() { diff --git a/core/src/main/java/jp/aegif/nemaki/model/User.java b/core/src/main/java/jp/aegif/nemaki/model/User.java index 9aba5651..59e52d21 100644 --- a/core/src/main/java/jp/aegif/nemaki/model/User.java +++ b/core/src/main/java/jp/aegif/nemaki/model/User.java @@ -127,7 +127,7 @@ public void setPasswordHash(String passwordHash) { } public Boolean isAdmin() { - return admin; + return admin == null ? false : admin; } public void setAdmin(Boolean admin) { diff --git a/core/src/main/java/jp/aegif/nemaki/rest/AuthenticationFilter.java b/core/src/main/java/jp/aegif/nemaki/rest/AuthenticationFilter.java index 376ec69d..13256ad7 100644 --- a/core/src/main/java/jp/aegif/nemaki/rest/AuthenticationFilter.java +++ b/core/src/main/java/jp/aegif/nemaki/rest/AuthenticationFilter.java @@ -37,6 +37,8 @@ import org.apache.chemistry.opencmis.server.impl.CallContextImpl; import org.apache.chemistry.opencmis.server.shared.HttpUtils; import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; @@ -53,8 +55,8 @@ public class AuthenticationFilter implements Filter { private AuthenticationService authenticationService; private RepositoryInfoMap repositoryInfoMap; private final String TOKEN_FALSE = "false"; - - private Logger logger = Logger.getLogger(AuthenticationFilter.class); + + private Log log = LogFactory.getLog(AuthenticationFilter.class); @Override public void init(FilterConfig filterConfig) throws ServletException { @@ -70,11 +72,11 @@ public void doFilter(ServletRequest req, ServletResponse res, if(auth){ chain.doFilter(req, res); }else{ - logger.error("REST API Unauthorized!"); + log.error("REST API Unauthorized!"); hres.sendError(HttpServletResponse.SC_UNAUTHORIZED); } } - + public boolean login(HttpServletRequest request, HttpServletResponse response){ String repositoryId = getRepositoryId(request); @@ -85,16 +87,16 @@ public boolean login(HttpServletRequest request, HttpServletResponse response){ for(String key : map.keySet()){ ctxt.put(key, map.get(key)); } - + boolean auth = authenticationService.login(ctxt); - + //Add attributes to Jersey @Context parameter - //TODO hard-coded key + //TODO hard-coded key request.setAttribute("CallContext", ctxt); - + return auth; } - + private String getRepositoryId(HttpServletRequest request){ // split path String[] pathFragments = HttpUtils.splitPath(request); @@ -111,19 +113,19 @@ private String getRepositoryId(HttpServletRequest request){ return repositoryInfoMap.getSuperUsers().getId(); } } - + return null; } - + @Override public void destroy() { // TODO Auto-generated method stub } - + private boolean checkResourceEnabled(HttpServletRequest request){ boolean enabled = true; - + String pathInfo = request.getPathInfo(); if(pathInfo.startsWith("/user")){ String userResourceEnabled = propertyManager.readValue(PropertyKey.REST_USER_ENABLED); @@ -146,10 +148,10 @@ private boolean checkResourceEnabled(HttpServletRequest request){ }else{ enabled = false; } - + return enabled; } - + public void setPropertyManager(PropertyManager propertyManager) { this.propertyManager = propertyManager; } diff --git a/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/DefaultLogger.java b/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/DefaultLogger.java index e6a72b15..be6e086a 100644 --- a/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/DefaultLogger.java +++ b/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/DefaultLogger.java @@ -30,7 +30,7 @@ public void init() { } public Object aroundMethod(ProceedingJoinPoint jp) throws Throwable{ - + StringBuilder sb = new StringBuilder(); Object[] args = jp.getArgs(); @@ -44,7 +44,7 @@ public Object aroundMethod(ProceedingJoinPoint jp) throws Throwable{ sb.append(userId + " : "); } } - + //Method name if(fullQualifiedName){ sb.append(jp.getTarget().getClass().getName()); @@ -55,12 +55,12 @@ public Object aroundMethod(ProceedingJoinPoint jp) throws Throwable{ if(arguments){ sb.append(Arrays.asList(args)); } - + //Before advice if(beforeEnabled){ log.info(sb.toString()); } - + //Execute method try{ Object result = jp.proceed(); @@ -70,10 +70,10 @@ public Object aroundMethod(ProceedingJoinPoint jp) throws Throwable{ sb.append(" returned "); if (returnValue && result != null) sb.append(result.toString()); - + log.info(sb.toString()); } - + return result; }catch(Exception e){ log.error("Error:", e); @@ -93,7 +93,7 @@ private CallContext getCallContext(Object[] args){ } return null; } - + public void setLogLevel(String logLevel) { this.logLevel = logLevel; } diff --git a/core/src/main/webapp/WEB-INF/classes/log4j.tomcat.xml b/core/src/main/webapp/WEB-INF/classes/log4j.tomcat.xml index 9486cb45..4148a88c 100644 --- a/core/src/main/webapp/WEB-INF/classes/log4j.tomcat.xml +++ b/core/src/main/webapp/WEB-INF/classes/log4j.tomcat.xml @@ -10,7 +10,7 @@ - + diff --git a/core/src/main/webapp/WEB-INF/classes/log4j.xml b/core/src/main/webapp/WEB-INF/classes/log4j.xml index 0e4e8b78..7d930ab0 100644 --- a/core/src/main/webapp/WEB-INF/classes/log4j.xml +++ b/core/src/main/webapp/WEB-INF/classes/log4j.xml @@ -2,39 +2,23 @@ - - - - - - - - - - - - - - - - - - - - - + + + - + + + \ No newline at end of file diff --git a/core/src/main/webapp/WEB-INF/classes/nemakiware.properties b/core/src/main/webapp/WEB-INF/classes/nemakiware.properties index ab36d5a2..ea8329b9 100644 --- a/core/src/main/webapp/WEB-INF/classes/nemakiware.properties +++ b/core/src/main/webapp/WEB-INF/classes/nemakiware.properties @@ -60,11 +60,11 @@ log.aspect.expression=execution(* jp.aegif.nemaki.cmis.service..*Impl.*(..)) and log.config.path=log4j.xml log.level=info log.return.value=false -log.fqn=true +log.fqn=false log.arguments=false -log.before=true +log.before=false log.after=false -log.callcontext=true +log.callcontext=false ###Cache cache.cmis.enabled=true From c46c0527f50c15850f79584e2ada8df03488eedd Mon Sep 17 00:00:00 2001 From: git -v Date: Tue, 5 Jan 2016 15:18:10 +0900 Subject: [PATCH 11/20] Modify : log formatting --- .../impl/ContentServiceImpl.java | 11 +- .../aspect/impl/PermissionServiceImpl.java | 10 +- .../cmis/factory/CmisServiceFactory.java | 4 +- .../cmis/service/impl/ObjectServiceImpl.java | 1898 ++++++++--------- .../src/main/webapp/WEB-INF/classes/log4j.xml | 2 +- 5 files changed, 962 insertions(+), 963 deletions(-) diff --git a/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java index fa805e24..04d7c87c 100644 --- a/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java @@ -447,7 +447,7 @@ public Document createDocument(CallContext callContext, String repositoryId, Pro // Create Document document = contentDaoService.create(repositoryId, d); - log.debug(String.format("[%s][%s][%s]Create entry on couchdb successfully.",repositoryId, document.getId(), contentStream.getFileName())); + log.debug(String.format("[Repository=%s][DocumentId=%s][FileName=%s]Create entry on couchdb successfully.",repositoryId, document.getId(), contentStream.getFileName())); // Update versionSeriesId#versionSeriesCheckedOutId after creating a PWC if (versioningState == VersioningState.CHECKEDOUT) { @@ -456,13 +456,11 @@ public Document createDocument(CallContext callContext, String repositoryId, Pro // Write change event writeChangeEvent(callContext, repositoryId, document, ChangeType.CREATED); + log.debug(String.format("[Repository=%s][DocumentId=%s][FileName=%s]Write change event successfully.",repositoryId, document.getId(), contentStream.getFileName())); + // Call Solr indexing(optional) - try{ - solrUtil.callSolrIndexing(repositoryId); - }catch(Exception ex){ - log.error(String.format("[%s][%s][%s]Solr indexing falure : %s",repositoryId, document.getId(), contentStream.getFileName(), ex)); - } + solrUtil.callSolrIndexing(repositoryId); return document; } @@ -527,6 +525,7 @@ public Document createDocumentWithNewStream(CallContext callContext, String repo // Create Document result = contentDaoService.create(repositoryId, copy); + // Record the change event writeChangeEvent(callContext, repositoryId, result, ChangeType.CREATED); diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java index 17efa34c..6c7b3657 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java @@ -111,7 +111,7 @@ public Boolean checkPermission(CallContext callContext, String repositoryId, Str if (u != null & u.isAdmin()) { - log.debug(String.format("[%s][User:%s][Permission:true] is_admin? => %s" , content.getName(), callContext.getUsername(), u.isAdmin())); + log.debug(String.format("[Repository=%s][FileName=%s][User=%s][Permission=true] is_admin? => %s" ,repositoryId, content.getName(), callContext.getUsername(), u.isAdmin())); return true; } @@ -122,7 +122,7 @@ public Boolean checkPermission(CallContext callContext, String repositoryId, Str if(document.isPrivateWorkingCopy()){ VersionSeries vs = contentService.getVersionSeries(repositoryId, document); if(!callContext.getUsername().equals(vs.getVersionSeriesCheckedOutBy())){ - log.debug(String.format("[%s][User:%s][Permission:false] PWS correct user => %s ", content.getName(),callContext.getUsername(), vs.getVersionSeriesCheckedOutBy())); + log.debug(String.format("[Repository=%s][FileName=%s][User=%s][Permission=false] PWS correct user => %s ",repositoryId, content.getName(),callContext.getUsername(), vs.getVersionSeriesCheckedOutBy())); return false; } } @@ -136,13 +136,13 @@ public Boolean checkPermission(CallContext callContext, String repositoryId, Str Relationship relationship = (Relationship)content; boolean hasRelationshipPermission = checkRelationshipPermission(callContext, repositoryId, key, relationship); - log.debug(String.format("[%s][User:%s][Permission:%s] Is relationship. ", content.getName(), callContext.getUsername(),hasRelationshipPermission)); + log.debug(String.format("[Repository=%s][FileName=%s][User=%s][Permission=%s] Is relationship. ",repositoryId, content.getName(), callContext.getUsername(),hasRelationshipPermission)); return hasRelationshipPermission; } // Void Acl fails(but Admin can do an action) if (acl == null){ - log.debug(String.format("[%s][User:%s][Permission:false] No Acl! ", content.getName(), callContext.getUsername())); + log.debug(String.format("[Repository=%s][FileName=%s][User=%s][Permission=false] No Acl! ",repositoryId, content.getName(), callContext.getUsername())); return false; } @@ -170,7 +170,7 @@ public Boolean checkPermission(CallContext callContext, String repositoryId, Str // Check mapping between the user and the content boolean calcPermission = checkCalculatedPermissions(repositoryId, key, userPermissions); - log.debug(String.format("[%s][User:%s][Permission:%s] Check Mapping. ", content.getName(), callContext.getUsername(), calcPermission)); + log.debug(String.format("[Repository=%s][FileName=%s][User=%s][Permission=%s] Check Mapping. ",repositoryId, content.getName(), callContext.getUsername(), calcPermission)); return calcPermission; } diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java b/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java index a6804544..9eeae09d 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java @@ -68,7 +68,7 @@ public org.apache.chemistry.opencmis.commons.server.CmisService getService(CallC if (auth) { - String msg = String.format("[repository=%1$s][userName=%2$s]Authentication succeeded",repositryId, userName); + String msg = String.format("[Repository=%1$s][userName=%2$s]Authentication succeeded",repositryId, userName); log.info(msg); // Create CmisService @@ -80,7 +80,7 @@ public org.apache.chemistry.opencmis.commons.server.CmisService getService(CallC return wrapper; } else { - String msg = String.format("[repository=%1$s][userName=%2$s]Authentication failed",repositryId, userName); + String msg = String.format("[Repository=%1$s][UserName=%2$s]Authentication failed",repositryId, userName); throw new CmisUnauthorizedException(msg, BigInteger.valueOf(401)); } } diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java index 945308c3..67de0599 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java @@ -1,949 +1,949 @@ -/******************************************************************************* - * Copyright (c) 2013 aegif. - * - * This file is part of NemakiWare. - * - * NemakiWare 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 3 of the License, or - * (at your option) any later version. - * - * NemakiWare 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 NemakiWare. - * If not, see . - * - * Contributors: - * linzhixing(https://github.com/linzhixing) - initial API and implementation - ******************************************************************************/ -package jp.aegif.nemaki.cmis.service.impl; - -import java.io.InputStream; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; - -import org.apache.chemistry.opencmis.commons.PropertyIds; -import org.apache.chemistry.opencmis.commons.data.Acl; -import org.apache.chemistry.opencmis.commons.data.AllowableActions; -import org.apache.chemistry.opencmis.commons.data.BulkUpdateObjectIdAndChangeToken; -import org.apache.chemistry.opencmis.commons.data.ContentStream; -import org.apache.chemistry.opencmis.commons.data.ExtensionsData; -import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData; -import org.apache.chemistry.opencmis.commons.data.ObjectData; -import org.apache.chemistry.opencmis.commons.data.PermissionMapping; -import org.apache.chemistry.opencmis.commons.data.Properties; -import org.apache.chemistry.opencmis.commons.data.RenditionData; -import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition; -import org.apache.chemistry.opencmis.commons.definitions.FolderTypeDefinition; -import org.apache.chemistry.opencmis.commons.definitions.RelationshipTypeDefinition; -import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition; -import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; -import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships; -import org.apache.chemistry.opencmis.commons.enums.UnfileObject; -import org.apache.chemistry.opencmis.commons.enums.VersioningState; -import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException; -import org.apache.chemistry.opencmis.commons.impl.dataobjects.BulkUpdateObjectIdAndChangeTokenImpl; -import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl; -import org.apache.chemistry.opencmis.commons.impl.dataobjects.FailedToDeleteDataImpl; -import org.apache.chemistry.opencmis.commons.impl.dataobjects.RenditionDataImpl; -import org.apache.chemistry.opencmis.commons.server.CallContext; -import org.apache.chemistry.opencmis.commons.spi.Holder; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import jp.aegif.nemaki.businesslogic.ContentService; -import jp.aegif.nemaki.cmis.aspect.CompileService; -import jp.aegif.nemaki.cmis.aspect.ExceptionService; -import jp.aegif.nemaki.cmis.aspect.query.solr.SolrUtil; -import jp.aegif.nemaki.cmis.aspect.type.TypeManager; -import jp.aegif.nemaki.cmis.service.ObjectService; -import jp.aegif.nemaki.model.AttachmentNode; -import jp.aegif.nemaki.model.Content; -import jp.aegif.nemaki.model.Document; -import jp.aegif.nemaki.model.Folder; -import jp.aegif.nemaki.model.Item; -import jp.aegif.nemaki.model.Policy; -import jp.aegif.nemaki.model.Relationship; -import jp.aegif.nemaki.model.Rendition; -import jp.aegif.nemaki.model.VersionSeries; -import jp.aegif.nemaki.util.DataUtil; -import jp.aegif.nemaki.util.cache.NemakiCache; -import jp.aegif.nemaki.util.cache.NemakiCachePool; -import jp.aegif.nemaki.util.constant.DomainType; - -public class ObjectServiceImpl implements ObjectService { - - private static final Log log = LogFactory - .getLog(ObjectServiceImpl.class); - - private TypeManager typeManager; - private ContentService contentService; - private ExceptionService exceptionService; - private CompileService compileService; - private SolrUtil solrUtil; - private NemakiCachePool nemakiCachePool; - - @Override - public ObjectData getObjectByPath(CallContext callContext, String repositoryId, - String path, String filter, - Boolean includeAllowableActions, IncludeRelationships includeRelationships, - String renditionFilter, Boolean includePolicyIds, - Boolean includeAcl, ExtensionsData extension) { - // ////////////////// - // General Exception - // ////////////////// - exceptionService.invalidArgumentRequired("objectId", path); - // FIXME path is not preserved in db. - Content content = contentService.getContentByPath(repositoryId, path); - // TODO create objectNotFoundByPath method - exceptionService.objectNotFound(DomainType.OBJECT, content, path); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_GET_PROPERTIES_OBJECT, content); - - // ////////////////// - // Body of the method - // ////////////////// - return compileService.compileObjectData(callContext, repositoryId, - content, filter, includeAllowableActions, - includeRelationships, renditionFilter, includeAcl); - } - - @Override - public ObjectData getObject(CallContext callContext, String repositoryId, - String objectId, String filter, - Boolean includeAllowableActions, IncludeRelationships includeRelationships, - String renditionFilter, Boolean includePolicyIds, - Boolean includeAcl, ExtensionsData extension) { - // ////////////////// - // General Exception - // ////////////////// - exceptionService.invalidArgumentRequired("objectId", objectId); - Content content = contentService.getContent(repositoryId, objectId); - // WORK AROUND: getObject(versionSeriesId) is interpreted as - // getDocumentOflatestVersion - if (content == null) { - VersionSeries versionSeries = contentService - .getVersionSeries(repositoryId, objectId); - if (versionSeries != null) { - content = contentService.getDocumentOfLatestVersion(repositoryId, objectId); - } - } - exceptionService.objectNotFound(DomainType.OBJECT, content, objectId); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_GET_PROPERTIES_OBJECT, content); - - // ////////////////// - // Body of the method - // ////////////////// - ObjectData object = compileService.compileObjectData(callContext, - repositoryId, content, filter, includeAllowableActions, - includeRelationships, null, includeAcl); - - return object; - } - - @Override - public ContentStream getContentStream(CallContext callContext, - String repositoryId, String objectId, String streamId, - BigInteger offset, BigInteger length) { - // ////////////////// - // General Exception - // ////////////////// - exceptionService.invalidArgumentRequired("objectId", objectId); - Content content = contentService.getContent(repositoryId, objectId); - exceptionService.objectNotFound(DomainType.OBJECT, content, objectId); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_GET_PROPERTIES_OBJECT, content); - - // ////////////////// - // Body of the method - // ////////////////// - if (streamId == null) { - return getContentStreamInternal(repositoryId, content, offset, length); - } else { - return getRenditionStream(repositoryId, content, streamId); - } - } - - // TODO Implement HTTP range(offset and length of stream), though it is not - // obligatory. - private ContentStream getContentStreamInternal(String repositoryId, - Content content, BigInteger rangeOffset, BigInteger rangeLength) { - if (!content.isDocument()) { - exceptionService - .constraint(content.getId(), - "getContentStream cannnot be invoked to other than document type."); - } - Document document = (Document) content; - exceptionService.constraintContentStreamDownload(repositoryId, document); - AttachmentNode attachment = contentService.getAttachment(repositoryId, document - .getAttachmentNodeId()); - attachment.setRangeOffset(rangeOffset); - attachment.setRangeLength(rangeLength); - - // Set content stream - BigInteger length = BigInteger.valueOf(attachment.getLength()); - String name = attachment.getName(); - String mimeType = attachment.getMimeType(); - InputStream is = attachment.getInputStream(); - ContentStream cs = new ContentStreamImpl(name, length, mimeType, is); - - return cs; - } - - private ContentStream getRenditionStream(String repositoryId, Content content, String streamId) { - if (!content.isDocument() && !content.isFolder()) { - exceptionService - .constraint(content.getId(), - "getRenditionStream cannnot be invoked to other than document or folder type."); - } - - exceptionService.constraintRenditionStreamDownload(content, streamId); - - Rendition rendition = contentService.getRendition(repositoryId, streamId); - - BigInteger length = BigInteger.valueOf(rendition.getLength()); - String mimeType = rendition.getMimetype(); - InputStream is = rendition.getInputStream(); - ContentStream cs = new ContentStreamImpl("preview_" + streamId, length, mimeType, is); - - return cs; - } - - @Override - public List getRenditions(CallContext callContext, - String repositoryId, String objectId, String renditionFilter, - BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) { - List renditions = contentService.getRenditions(repositoryId, objectId); - - List results = new ArrayList(); - for (Rendition rnd : renditions) { - RenditionDataImpl data = new RenditionDataImpl(rnd.getId(), - rnd.getMimetype(), BigInteger.valueOf(rnd.getLength()), - rnd.getKind(), rnd.getTitle(), BigInteger.valueOf(rnd - .getWidth()), BigInteger.valueOf(rnd.getHeight()), - rnd.getRenditionDocumentId()); - results.add(data); - } - return results; - } - - @Override - public AllowableActions getAllowableActions(CallContext callContext, - String repositoryId, String objectId) { - // ////////////////// - // General Exception - // ////////////////// - exceptionService.invalidArgumentRequired("objectId", objectId); - Content content = contentService.getContent(repositoryId, objectId); - exceptionService.objectNotFound(DomainType.OBJECT, content, objectId); - // NOTE: The permission key doesn't exist according to CMIS - // specification. - - // ////////////////// - // Body of the method - // ////////////////// - return compileService.compileAllowableActions(callContext, - repositoryId, content); - } - - @Override - public ObjectData create(CallContext callContext, String repositoryId, - Properties properties, String folderId, - ContentStream contentStream, VersioningState versioningState, - List policies, ExtensionsData extension) { - - String typeId = DataUtil.getObjectTypeId(properties); - TypeDefinition type = typeManager.getTypeDefinition(repositoryId, typeId); - if (type == null) { - throw new CmisObjectNotFoundException("Type '" + typeId - + "' is unknown!"); - } - - String objectId = null; - // TODO ACE can be set ! - if (type.getBaseTypeId() == BaseTypeId.CMIS_DOCUMENT) { - objectId = createDocument(callContext, repositoryId, properties, - folderId, contentStream, versioningState, null, null, null); - } else if (type.getBaseTypeId() == BaseTypeId.CMIS_FOLDER) { - objectId = createFolder(callContext, repositoryId, properties, - folderId, policies, null, null, extension); - } else if (type.getBaseTypeId() == BaseTypeId.CMIS_RELATIONSHIP) { - objectId = createRelationship(callContext, repositoryId, properties, - policies, null, null, extension); - } else if (type.getBaseTypeId() == BaseTypeId.CMIS_POLICY) { - objectId = createPolicy(callContext, repositoryId, properties, folderId, - policies, null, null, extension); - } else if (type.getBaseTypeId() == BaseTypeId.CMIS_ITEM) { - objectId = createItem(callContext, repositoryId, properties, folderId, - policies, null, null, extension); - } else { - throw new CmisObjectNotFoundException( - "Cannot create object of type '" + typeId + "'!"); - } - - log.debug(String.format("[%s][%s][%s]Creating object data by compileService ...",repositoryId, objectId, contentStream.getFileName())); - ObjectData object = compileService.compileObjectData(callContext, - repositoryId, contentService.getContent(repositoryId, objectId), null, - false, IncludeRelationships.NONE, null, false); - log.debug(String.format("[%s][%s][%s]Create object data by compileService successfully.",repositoryId, objectId, contentStream.getFileName())); - - return object; - } - - @Override - public String createFolder(CallContext callContext, String repositoryId, - Properties properties, String folderId, List policies, - Acl addAces, Acl removeAces, ExtensionsData extension) { - FolderTypeDefinition td = (FolderTypeDefinition) typeManager - .getTypeDefinition(repositoryId, DataUtil.getObjectTypeId(properties)); - Folder parentFolder = contentService.getFolder(repositoryId, folderId); - - // ////////////////// - // General Exception - // ////////////////// - exceptionService.objectNotFoundParentFolder(repositoryId, folderId, parentFolder); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_CREATE_FOLDER_FOLDER, parentFolder); - - // ////////////////// - // Specific Exception - // ////////////////// - exceptionService.constraintBaseTypeId(repositoryId, - properties, BaseTypeId.CMIS_FOLDER); - exceptionService.constraintAllowedChildObjectTypeId(parentFolder, - properties); - exceptionService.constraintPropertyValue(repositoryId, td, - properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); - exceptionService - .constraintCotrollablePolicies(td, policies, properties); - exceptionService.constraintCotrollableAcl(td, addAces, removeAces, - properties); - exceptionService.constraintPermissionDefined(repositoryId, addAces, null); - exceptionService.constraintPermissionDefined(repositoryId, removeAces, null); - exceptionService.nameConstraintViolation(properties, parentFolder); - - // ////////////////// - // Body of the method - // ////////////////// - Folder folder = contentService.createFolder(callContext, repositoryId, - properties, parentFolder); - return folder.getId(); - } - - @Override - public String createDocument(CallContext callContext, - String repositoryId, Properties properties, - String folderId, ContentStream contentStream, - VersioningState versioningState, List policies, Acl addAces, Acl removeAces) { - String objectTypeId = DataUtil.getIdProperty(properties, - PropertyIds.OBJECT_TYPE_ID); - DocumentTypeDefinition td = (DocumentTypeDefinition) typeManager - .getTypeDefinition(repositoryId, objectTypeId); - Folder parentFolder = contentService.getFolder(repositoryId, folderId); - - // ////////////////// - // General Exception - // ////////////////// - exceptionService.invalidArgumentRequired("properties", properties); - exceptionService.invalidArgumentRequiredParentFolderId(repositoryId, folderId); - exceptionService.objectNotFoundParentFolder(repositoryId, folderId, parentFolder); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_CREATE_FOLDER_FOLDER, parentFolder); - - // ////////////////// - // Specific Exception - // ////////////////// - exceptionService.constraintBaseTypeId(repositoryId, - properties, BaseTypeId.CMIS_DOCUMENT); - exceptionService.constraintAllowedChildObjectTypeId(parentFolder, - properties); - exceptionService.constraintPropertyValue(repositoryId, td, - properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); - exceptionService.constraintContentStreamRequired(td, contentStream); - exceptionService.constraintControllableVersionable(td, versioningState, - null); - versioningState = (td.isVersionable() && versioningState == null) ? VersioningState.MAJOR : versioningState; - exceptionService - .constraintCotrollablePolicies(td, policies, properties); - exceptionService.constraintCotrollableAcl(td, addAces, removeAces, - properties); - exceptionService.constraintPermissionDefined(repositoryId, addAces, null); - exceptionService.constraintPermissionDefined(repositoryId, removeAces, null); - exceptionService.streamNotSupported(td, contentStream); - exceptionService.nameConstraintViolation(properties, parentFolder); - - // ////////////////// - // Body of the method - // ////////////////// - Document document = contentService.createDocument(callContext, - repositoryId, properties, parentFolder, contentStream, versioningState, null); - return document.getId(); - } - - @Override - public String createDocumentFromSource(CallContext callContext, - String repositoryId, String sourceId, Properties properties, - String folderId, VersioningState versioningState, - List policies, Acl addAces, Acl removeAces) { - Document original = contentService.getDocument(repositoryId, sourceId); - DocumentTypeDefinition td = (DocumentTypeDefinition) typeManager - .getTypeDefinition(repositoryId, original.getObjectType()); - - // ////////////////// - // General Exception - // ////////////////// - exceptionService.invalidArgumentRequired("properties", properties); - exceptionService.invalidArgumentRequiredParentFolderId(repositoryId, folderId); - Folder parentFolder = contentService.getFolder(repositoryId, folderId); - exceptionService.objectNotFoundParentFolder(repositoryId, folderId, parentFolder); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_CREATE_FOLDER_FOLDER, parentFolder); - - // ////////////////// - // Specific Exception - // ////////////////// - exceptionService.constraintBaseTypeId(repositoryId, - properties, BaseTypeId.CMIS_DOCUMENT); - exceptionService.constraintAllowedChildObjectTypeId(parentFolder, - properties); - exceptionService.constraintPropertyValue(repositoryId, td, - properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); - exceptionService.constraintControllableVersionable(td, versioningState, - null); - versioningState = (td.isVersionable() && versioningState == null) ? VersioningState.MAJOR : versioningState; - exceptionService - .constraintCotrollablePolicies(td, policies, properties); - exceptionService.constraintCotrollableAcl(td, addAces, removeAces, - properties); - exceptionService.constraintPermissionDefined(repositoryId, addAces, null); - exceptionService.constraintPermissionDefined(repositoryId, removeAces, null); - exceptionService.nameConstraintViolation(properties, parentFolder); - - // ////////////////// - // Body of the method - // ////////////////// - Document document = contentService.createDocumentFromSource( - callContext, repositoryId, properties, parentFolder, - original, versioningState, policies, addAces, removeAces); - return document.getId(); - } - - @Override - public void setContentStream(CallContext callContext, - String repositoryId, Holder objectId, - boolean overwriteFlag, ContentStream contentStream, Holder changeToken) { - // ////////////////// - // General Exception - // ////////////////// - String id = objectId.getValue(); - - exceptionService.invalidArgumentRequiredString("objectId", id); - exceptionService - .invalidArgumentRequired("contentStream", contentStream); - Document doc = (Document) contentService.getContent(repositoryId, id); - exceptionService.objectNotFound(DomainType.OBJECT, doc, id); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_SET_CONTENT_DOCUMENT, doc); - DocumentTypeDefinition td = (DocumentTypeDefinition) typeManager - .getTypeDefinition(repositoryId, doc.getObjectType()); - exceptionService.constraintImmutable(repositoryId, doc, td); - - // ////////////////// - // Specific Exception - // ////////////////// - exceptionService.contentAlreadyExists(doc, overwriteFlag); - exceptionService.streamNotSupported(td, contentStream); - exceptionService.updateConflict(doc, changeToken); - exceptionService.versioning(doc); - Folder parent = contentService.getParent(repositoryId, id); - exceptionService.objectNotFoundParentFolder(repositoryId, id, parent); - - // ////////////////// - // Body of the method - // ////////////////// - String oldId = objectId.getValue(); - - // TODO Externalize versioningState - if(doc.isPrivateWorkingCopy()){ - Document result = contentService.replacePwc(callContext, repositoryId, - doc, contentStream); - objectId.setValue(result.getId()); - }else{ - Document result = contentService.createDocumentWithNewStream(callContext, repositoryId, - doc, contentStream); - objectId.setValue(result.getId()); - } - - nemakiCachePool.get(repositoryId).removeCmisCache(oldId); - } - - @Override - public void deleteContentStream(CallContext callContext, - String repositoryId, Holder objectId, - Holder changeToken, ExtensionsData extension) { - // ////////////////// - // Exception - // ////////////////// - exceptionService.invalidArgumentRequiredHolderString("objectId", - objectId); - Document document = contentService.getDocument(repositoryId, objectId.getValue()); - exceptionService.objectNotFound(DomainType.OBJECT, document, - document.getId()); - exceptionService.constraintContentStreamRequired(repositoryId, document); - - // ////////////////// - // Body of the method - // ////////////////// - contentService.deleteContentStream(callContext, repositoryId, objectId); - - nemakiCachePool.get(repositoryId).removeCmisCache(objectId.getValue()); - } - - @Override - public void appendContentStream(CallContext callContext, - String repositoryId, Holder objectId, - Holder changeToken, ContentStream contentStream, - boolean isLastChunk, ExtensionsData extension) { - // ////////////////// - // General Exception - // ////////////////// - String id = objectId.getValue(); - - exceptionService.invalidArgumentRequiredString("objectId", id); - exceptionService - .invalidArgumentRequired("contentStream", contentStream); - Document doc = (Document) contentService.getContent(repositoryId, id); - exceptionService.objectNotFound(DomainType.OBJECT, doc, id); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_SET_CONTENT_DOCUMENT, doc); - DocumentTypeDefinition td = (DocumentTypeDefinition) typeManager - .getTypeDefinition(repositoryId, doc.getObjectType()); - exceptionService.constraintImmutable(repositoryId, doc, td); - - // ////////////////// - // Specific Exception - // ////////////////// - exceptionService.streamNotSupported(td, contentStream); - exceptionService.updateConflict(doc, changeToken); - exceptionService.versioning(doc); - - // ////////////////// - // Body of the method - // ////////////////// - contentService.appendAttachment(callContext, repositoryId, objectId, - changeToken, contentStream, isLastChunk, extension); - - nemakiCachePool.get(repositoryId).removeCmisCache(objectId.getValue()); - } - - @Override - public String createRelationship(CallContext callContext, - String repositoryId, Properties properties, List policies, - Acl addAces, Acl removeAces, ExtensionsData extension) { - String objectTypeId = DataUtil.getIdProperty(properties, - PropertyIds.OBJECT_TYPE_ID); - RelationshipTypeDefinition td = (RelationshipTypeDefinition) typeManager - .getTypeDefinition(repositoryId, objectTypeId); - // ////////////////// - // Exception - // ////////////////// - exceptionService.invalidArgumentRequiredCollection("properties", - properties.getPropertyList()); - String sourceId = DataUtil.getIdProperty(properties, - PropertyIds.SOURCE_ID); - if (sourceId != null) { - Content source = contentService.getContent(repositoryId, DataUtil - .getStringProperty(properties, PropertyIds.SOURCE_ID)); - if (source == null) - exceptionService.constraintAllowedSourceTypes(td, source); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_CREATE_RELATIONSHIP_SOURCE, source); - } - String targetId = DataUtil.getIdProperty(properties, - PropertyIds.TARGET_ID); - if (targetId != null) { - Content target = contentService.getContent(repositoryId, DataUtil - .getStringProperty(properties, PropertyIds.TARGET_ID)); - if (target == null) - exceptionService.constraintAllowedTargetTypes(td, target); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_CREATE_RELATIONSHIP_TARGET, target); - } - - exceptionService.constraintBaseTypeId(repositoryId, - properties, BaseTypeId.CMIS_RELATIONSHIP); - exceptionService.constraintPropertyValue(repositoryId, td, - properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); - exceptionService - .constraintCotrollablePolicies(td, policies, properties); - exceptionService.constraintCotrollableAcl(td, addAces, removeAces, - properties); - exceptionService.constraintPermissionDefined(repositoryId, addAces, null); - exceptionService.constraintPermissionDefined(repositoryId, removeAces, null); - exceptionService.nameConstraintViolation(properties, null); - - // ////////////////// - // Body of the method - // ////////////////// - Relationship relationship = contentService.createRelationship( - callContext, repositoryId, properties, policies, addAces, - removeAces, extension); - nemakiCachePool.get(repositoryId).removeCmisCache(relationship.getSourceId()); - nemakiCachePool.get(repositoryId).removeCmisCache(relationship.getTargetId()); - - return relationship.getId(); - } - - @Override - public String createPolicy(CallContext callContext, String repositoryId, - Properties properties, String folderId, List policies, - Acl addAces, Acl removeAces, ExtensionsData extension) { - // ////////////////// - // General Exception - // ////////////////// - exceptionService.invalidArgumentRequiredCollection("properties", - properties.getPropertyList()); - // NOTE: folderId is ignored because policy is not filable in Nemaki - TypeDefinition td = typeManager.getTypeDefinition(repositoryId, DataUtil - .getIdProperty(properties, PropertyIds.OBJECT_TYPE_ID)); - exceptionService.constraintPropertyValue(repositoryId, td, - properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); - - // ////////////////// - // Specific Exception - // ////////////////// - exceptionService.constraintBaseTypeId(repositoryId, - properties, BaseTypeId.CMIS_POLICY); - // exceptionService.constraintAllowedChildObjectTypeId(parent, - // properties); - exceptionService - .constraintCotrollablePolicies(td, policies, properties); - exceptionService.constraintCotrollableAcl(td, addAces, removeAces, - properties); - // exceptionService.nameConstraintViolation(properties, parent); - - // ////////////////// - // Body of the method - // ////////////////// - Policy policy = contentService.createPolicy(callContext, repositoryId, - properties, policies, addAces, removeAces, extension); - return policy.getId(); - } - - @Override - public String createItem(CallContext callContext, String repositoryId, - Properties properties, String folderId, List policies, - Acl addAces, Acl removeAces, ExtensionsData extension) { - // ////////////////// - // General Exception - // ////////////////// - TypeDefinition td = typeManager.getTypeDefinition(repositoryId, DataUtil - .getObjectTypeId(properties)); - Folder parentFolder = contentService.getFolder(repositoryId, folderId); - exceptionService.objectNotFoundParentFolder(repositoryId, folderId, parentFolder); - exceptionService.invalidArgumentRequiredCollection("properties", - properties.getPropertyList()); - - // ////////////////// - // Specific Exception - // ////////////////// - exceptionService.constraintBaseTypeId(repositoryId, properties, BaseTypeId.CMIS_ITEM); - exceptionService.constraintPropertyValue(repositoryId, td, - properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); - exceptionService - .constraintCotrollablePolicies(td, policies, properties); - exceptionService.constraintCotrollableAcl(td, addAces, removeAces, - properties); - - // ////////////////// - // Body of the method - // ////////////////// - Item item = contentService.createItem(callContext, repositoryId, - properties, folderId, policies, addAces, removeAces, extension); - return item.getId(); - } - - @Override - public void updateProperties(CallContext callContext, - String repositoryId, Holder objectId, - Properties properties, Holder changeToken) { - - // ////////////////// - // Exception - // ////////////////// - Content content = checkExceptionBeforeUpdateProperties(callContext, - repositoryId, objectId, properties, changeToken); - - // ////////////////// - // Body of the method - // ////////////////// - String id = objectId.getValue(); - - contentService.updateProperties(callContext, repositoryId, properties, content); - - nemakiCachePool.get(repositoryId).removeCmisCache(id); - } - - private Content checkExceptionBeforeUpdateProperties( - CallContext callContext, String repositoryId, - Holder objectId, Properties properties, Holder changeToken) { - // ////////////////// - // General Exception - // ////////////////// - exceptionService.invalidArgumentRequiredHolderString("objectId", - objectId); - exceptionService.invalidArgumentRequiredCollection("properties", - properties.getPropertyList()); - Content content = contentService.getContent(repositoryId, objectId.getValue()); - exceptionService.objectNotFound(DomainType.OBJECT, content, - objectId.getValue()); - if (content.isDocument()) { - Document d = (Document) content; - exceptionService.versioning(d); - exceptionService.constraintUpdateWhenCheckedOut(repositoryId, callContext.getUsername(), d); - TypeDefinition typeDef = typeManager.getTypeDefinition(repositoryId, d); - exceptionService.constraintImmutable(repositoryId, d, typeDef); - } - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT, content); - exceptionService.updateConflict(content, changeToken); - - - - TypeDefinition tdf = typeManager.getTypeDefinition(repositoryId, content); - exceptionService.constraintPropertyValue(repositoryId, tdf, - properties, objectId.getValue()); - - return content; - } - - @Override - public List bulkUpdateProperties( - CallContext callContext, - String repositoryId, - List objectIdAndChangeToken, Properties properties, - List addSecondaryTypeIds, List removeSecondaryTypeIds, ExtensionsData extension) { - // ////////////////// - // General Exception - // ////////////////// - // Each permission is checked at each execution - exceptionService.invalidArgumentRequiredCollection( - "objectIdAndChangeToken", objectIdAndChangeToken); - exceptionService.invalidArgumentSecondaryTypeIds(repositoryId, properties); - - // ////////////////// - // Body of the method - // ////////////////// - List results = new ArrayList(); - - for (BulkUpdateObjectIdAndChangeToken idAndToken : objectIdAndChangeToken) { - try { - Content content = checkExceptionBeforeUpdateProperties( - callContext, repositoryId, - new Holder(idAndToken.getId()), - properties, new Holder(idAndToken.getChangeToken())); - contentService.updateProperties(callContext, repositoryId, - properties, content); - nemakiCachePool.get(repositoryId).removeCmisCache(content.getId()); - - BulkUpdateObjectIdAndChangeToken result = new BulkUpdateObjectIdAndChangeTokenImpl( - idAndToken.getId(), content.getId(), - String.valueOf(content.getChangeToken())); - results.add(result); - } catch (Exception e) { - // Don't throw an error - // Don't return any BulkUpdateObjectIdAndChangetoken - } - } - - return results; - } - - @Override - public void moveObject(CallContext callContext, String repositoryId, - Holder objectId, String sourceFolderId, String targetFolderId) { - // ////////////////// - // General Exception - // ////////////////// - exceptionService.invalidArgumentRequiredHolderString("objectId", - objectId); - exceptionService.invalidArgumentRequiredString("sourceFolderId", - sourceFolderId); - exceptionService.invalidArgumentRequiredString("targetFolderId", - targetFolderId); - Content content = contentService.getContent(repositoryId, objectId.getValue()); - exceptionService.objectNotFound(DomainType.OBJECT, content, - objectId.getValue()); - Folder source = contentService.getFolder(repositoryId, sourceFolderId); - exceptionService.objectNotFound(DomainType.OBJECT, source, - sourceFolderId); - Folder target = contentService.getFolder(repositoryId, targetFolderId); - exceptionService.objectNotFound(DomainType.OBJECT, target, - targetFolderId); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_MOVE_OBJECT, content); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_MOVE_SOURCE, source); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_MOVE_TARGET, target); - - // ////////////////// - // Body of the method - // ////////////////// - contentService.move(repositoryId, content, target); - - nemakiCachePool.get(repositoryId).removeCmisCache(content.getId()); - } - - private void deleteObjectInternal(CallContext callContext, String repositoryId, - String objectId, Boolean allVersions, Boolean deleteWithParent) { - // ////////////////// - // General Exception - // ////////////////// - exceptionService.invalidArgumentRequiredString("objectId", objectId); - Content content = contentService.getContent(repositoryId, objectId); - exceptionService.objectNotFound(DomainType.OBJECT, content, objectId); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_DELETE_OBJECT, content); - exceptionService.constraintDeleteRootFolder(repositoryId, objectId); - - // ////////////////// - // Body of the method - // ////////////////// - if (content.isDocument()) { - contentService.deleteDocument(callContext, repositoryId, - content.getId(), allVersions, deleteWithParent); - } else if (content.isFolder()) { - List children = contentService.getChildren(repositoryId, objectId); - if (!CollectionUtils.isEmpty(children)) { - exceptionService - .constraint(objectId, - "deleteObject method is invoked on a folder containing objects."); - } - contentService.delete(callContext, repositoryId, objectId, deleteWithParent); - - } else { - contentService.delete(callContext, repositoryId, objectId, deleteWithParent); - } - - nemakiCachePool.get(repositoryId).removeCmisCache(content.getId()); - } - - @Override - public void deleteObject(CallContext callContext, String repositoryId, - String objectId, Boolean allVersions) { - deleteObjectInternal(callContext, repositoryId, objectId, allVersions, false); - } - - @Override - public FailedToDeleteData deleteTree(CallContext callContext, - String repositoryId, String folderId, Boolean allVersions, - UnfileObject unfileObjects, Boolean continueOnFailure, ExtensionsData extension) { - // ////////////////// - // General Exception - // ////////////////// - exceptionService.invalidArgumentRequiredString("objectId", folderId); - Folder folder = contentService.getFolder(repositoryId, folderId); - exceptionService.permissionDenied(callContext, - repositoryId, PermissionMapping.CAN_DELETE_TREE_FOLDER, folder); - exceptionService.constraintDeleteRootFolder(repositoryId, folderId); - - // ////////////////// - // Specific Exception - // ////////////////// - if (folder == null) - exceptionService.constraint(folderId, - "deleteTree cannot be invoked on a non-folder object"); - - // ////////////////// - // Body of the method - // ////////////////// - // Delete descendants - List failureIds = new ArrayList(); - - List children = contentService.getChildren(repositoryId, folderId); - if (!CollectionUtils.isEmpty(children)) { - for (Content child : children) { - try { - if (child.isFolder()) { - deleteTree(callContext, repositoryId, child.getId(), allVersions, - unfileObjects, continueOnFailure, extension); - } else { - deleteObjectInternal(callContext, repositoryId, child.getId(), allVersions, true); - } - } catch (Exception e) { - StringBuilder sb = new StringBuilder(); - sb.append("objectId:").append(child.getId()).append(" failed to be deleted."); - - if (continueOnFailure) { - failureIds.add(child.getId()); - log.warn(sb.toString(), e); - continue; - } else { - log.error(sb.toString(), e); - } - } - } - } - - // Delete the folder itself - try { - deleteObjectInternal(callContext, repositoryId, folderId, allVersions, false); - } catch (Exception e) { - StringBuilder sb = new StringBuilder(); - sb.append("objectId:").append(folderId).append(" failed to be deleted."); - - if (continueOnFailure) { - failureIds.add(folderId); - log.warn(sb.toString(), e); - } else { - log.error(sb.toString(), e); - } - } - - /*failureIds = contentService.deleteTree(callContext, folderId, allVersions, - continueOnFailure, false);*/ - solrUtil.callSolrIndexing(repositoryId); - - // Check FailedToDeleteData - // FIXME Consider orphans that was failed to be deleted - FailedToDeleteDataImpl fdd = new FailedToDeleteDataImpl(); - - if (CollectionUtils.isNotEmpty(failureIds)) { - fdd.setIds(failureIds); - } else { - fdd.setIds(new ArrayList()); - } - return fdd; - } - - public void setContentService(ContentService contentService) { - this.contentService = contentService; - } - - public void setExceptionService(ExceptionService exceptionService) { - this.exceptionService = exceptionService; - } - - public void setCompileService(CompileService compileService) { - this.compileService = compileService; - } - - public void setTypeManager(TypeManager typeManager) { - this.typeManager = typeManager; - } - - public void setSolrUtil(SolrUtil solrUtil) { - this.solrUtil = solrUtil; - } - - public void setNemakiCachePool(NemakiCachePool nemakiCachePool) { - this.nemakiCachePool = nemakiCachePool; - } -} +/******************************************************************************* + * Copyright (c) 2013 aegif. + * + * This file is part of NemakiWare. + * + * NemakiWare 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 3 of the License, or + * (at your option) any later version. + * + * NemakiWare 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 NemakiWare. + * If not, see . + * + * Contributors: + * linzhixing(https://github.com/linzhixing) - initial API and implementation + ******************************************************************************/ +package jp.aegif.nemaki.cmis.service.impl; + +import java.io.InputStream; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import org.apache.chemistry.opencmis.commons.PropertyIds; +import org.apache.chemistry.opencmis.commons.data.Acl; +import org.apache.chemistry.opencmis.commons.data.AllowableActions; +import org.apache.chemistry.opencmis.commons.data.BulkUpdateObjectIdAndChangeToken; +import org.apache.chemistry.opencmis.commons.data.ContentStream; +import org.apache.chemistry.opencmis.commons.data.ExtensionsData; +import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData; +import org.apache.chemistry.opencmis.commons.data.ObjectData; +import org.apache.chemistry.opencmis.commons.data.PermissionMapping; +import org.apache.chemistry.opencmis.commons.data.Properties; +import org.apache.chemistry.opencmis.commons.data.RenditionData; +import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition; +import org.apache.chemistry.opencmis.commons.definitions.FolderTypeDefinition; +import org.apache.chemistry.opencmis.commons.definitions.RelationshipTypeDefinition; +import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition; +import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; +import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships; +import org.apache.chemistry.opencmis.commons.enums.UnfileObject; +import org.apache.chemistry.opencmis.commons.enums.VersioningState; +import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException; +import org.apache.chemistry.opencmis.commons.impl.dataobjects.BulkUpdateObjectIdAndChangeTokenImpl; +import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl; +import org.apache.chemistry.opencmis.commons.impl.dataobjects.FailedToDeleteDataImpl; +import org.apache.chemistry.opencmis.commons.impl.dataobjects.RenditionDataImpl; +import org.apache.chemistry.opencmis.commons.server.CallContext; +import org.apache.chemistry.opencmis.commons.spi.Holder; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import jp.aegif.nemaki.businesslogic.ContentService; +import jp.aegif.nemaki.cmis.aspect.CompileService; +import jp.aegif.nemaki.cmis.aspect.ExceptionService; +import jp.aegif.nemaki.cmis.aspect.query.solr.SolrUtil; +import jp.aegif.nemaki.cmis.aspect.type.TypeManager; +import jp.aegif.nemaki.cmis.service.ObjectService; +import jp.aegif.nemaki.model.AttachmentNode; +import jp.aegif.nemaki.model.Content; +import jp.aegif.nemaki.model.Document; +import jp.aegif.nemaki.model.Folder; +import jp.aegif.nemaki.model.Item; +import jp.aegif.nemaki.model.Policy; +import jp.aegif.nemaki.model.Relationship; +import jp.aegif.nemaki.model.Rendition; +import jp.aegif.nemaki.model.VersionSeries; +import jp.aegif.nemaki.util.DataUtil; +import jp.aegif.nemaki.util.cache.NemakiCache; +import jp.aegif.nemaki.util.cache.NemakiCachePool; +import jp.aegif.nemaki.util.constant.DomainType; + +public class ObjectServiceImpl implements ObjectService { + + private static final Log log = LogFactory + .getLog(ObjectServiceImpl.class); + + private TypeManager typeManager; + private ContentService contentService; + private ExceptionService exceptionService; + private CompileService compileService; + private SolrUtil solrUtil; + private NemakiCachePool nemakiCachePool; + + @Override + public ObjectData getObjectByPath(CallContext callContext, String repositoryId, + String path, String filter, + Boolean includeAllowableActions, IncludeRelationships includeRelationships, + String renditionFilter, Boolean includePolicyIds, + Boolean includeAcl, ExtensionsData extension) { + // ////////////////// + // General Exception + // ////////////////// + exceptionService.invalidArgumentRequired("objectId", path); + // FIXME path is not preserved in db. + Content content = contentService.getContentByPath(repositoryId, path); + // TODO create objectNotFoundByPath method + exceptionService.objectNotFound(DomainType.OBJECT, content, path); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_GET_PROPERTIES_OBJECT, content); + + // ////////////////// + // Body of the method + // ////////////////// + return compileService.compileObjectData(callContext, repositoryId, + content, filter, includeAllowableActions, + includeRelationships, renditionFilter, includeAcl); + } + + @Override + public ObjectData getObject(CallContext callContext, String repositoryId, + String objectId, String filter, + Boolean includeAllowableActions, IncludeRelationships includeRelationships, + String renditionFilter, Boolean includePolicyIds, + Boolean includeAcl, ExtensionsData extension) { + // ////////////////// + // General Exception + // ////////////////// + exceptionService.invalidArgumentRequired("objectId", objectId); + Content content = contentService.getContent(repositoryId, objectId); + // WORK AROUND: getObject(versionSeriesId) is interpreted as + // getDocumentOflatestVersion + if (content == null) { + VersionSeries versionSeries = contentService + .getVersionSeries(repositoryId, objectId); + if (versionSeries != null) { + content = contentService.getDocumentOfLatestVersion(repositoryId, objectId); + } + } + exceptionService.objectNotFound(DomainType.OBJECT, content, objectId); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_GET_PROPERTIES_OBJECT, content); + + // ////////////////// + // Body of the method + // ////////////////// + ObjectData object = compileService.compileObjectData(callContext, + repositoryId, content, filter, includeAllowableActions, + includeRelationships, null, includeAcl); + + return object; + } + + @Override + public ContentStream getContentStream(CallContext callContext, + String repositoryId, String objectId, String streamId, + BigInteger offset, BigInteger length) { + // ////////////////// + // General Exception + // ////////////////// + exceptionService.invalidArgumentRequired("objectId", objectId); + Content content = contentService.getContent(repositoryId, objectId); + exceptionService.objectNotFound(DomainType.OBJECT, content, objectId); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_GET_PROPERTIES_OBJECT, content); + + // ////////////////// + // Body of the method + // ////////////////// + if (streamId == null) { + return getContentStreamInternal(repositoryId, content, offset, length); + } else { + return getRenditionStream(repositoryId, content, streamId); + } + } + + // TODO Implement HTTP range(offset and length of stream), though it is not + // obligatory. + private ContentStream getContentStreamInternal(String repositoryId, + Content content, BigInteger rangeOffset, BigInteger rangeLength) { + if (!content.isDocument()) { + exceptionService + .constraint(content.getId(), + "getContentStream cannnot be invoked to other than document type."); + } + Document document = (Document) content; + exceptionService.constraintContentStreamDownload(repositoryId, document); + AttachmentNode attachment = contentService.getAttachment(repositoryId, document + .getAttachmentNodeId()); + attachment.setRangeOffset(rangeOffset); + attachment.setRangeLength(rangeLength); + + // Set content stream + BigInteger length = BigInteger.valueOf(attachment.getLength()); + String name = attachment.getName(); + String mimeType = attachment.getMimeType(); + InputStream is = attachment.getInputStream(); + ContentStream cs = new ContentStreamImpl(name, length, mimeType, is); + + return cs; + } + + private ContentStream getRenditionStream(String repositoryId, Content content, String streamId) { + if (!content.isDocument() && !content.isFolder()) { + exceptionService + .constraint(content.getId(), + "getRenditionStream cannnot be invoked to other than document or folder type."); + } + + exceptionService.constraintRenditionStreamDownload(content, streamId); + + Rendition rendition = contentService.getRendition(repositoryId, streamId); + + BigInteger length = BigInteger.valueOf(rendition.getLength()); + String mimeType = rendition.getMimetype(); + InputStream is = rendition.getInputStream(); + ContentStream cs = new ContentStreamImpl("preview_" + streamId, length, mimeType, is); + + return cs; + } + + @Override + public List getRenditions(CallContext callContext, + String repositoryId, String objectId, String renditionFilter, + BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) { + List renditions = contentService.getRenditions(repositoryId, objectId); + + List results = new ArrayList(); + for (Rendition rnd : renditions) { + RenditionDataImpl data = new RenditionDataImpl(rnd.getId(), + rnd.getMimetype(), BigInteger.valueOf(rnd.getLength()), + rnd.getKind(), rnd.getTitle(), BigInteger.valueOf(rnd + .getWidth()), BigInteger.valueOf(rnd.getHeight()), + rnd.getRenditionDocumentId()); + results.add(data); + } + return results; + } + + @Override + public AllowableActions getAllowableActions(CallContext callContext, + String repositoryId, String objectId) { + // ////////////////// + // General Exception + // ////////////////// + exceptionService.invalidArgumentRequired("objectId", objectId); + Content content = contentService.getContent(repositoryId, objectId); + exceptionService.objectNotFound(DomainType.OBJECT, content, objectId); + // NOTE: The permission key doesn't exist according to CMIS + // specification. + + // ////////////////// + // Body of the method + // ////////////////// + return compileService.compileAllowableActions(callContext, + repositoryId, content); + } + + @Override + public ObjectData create(CallContext callContext, String repositoryId, + Properties properties, String folderId, + ContentStream contentStream, VersioningState versioningState, + List policies, ExtensionsData extension) { + + String typeId = DataUtil.getObjectTypeId(properties); + TypeDefinition type = typeManager.getTypeDefinition(repositoryId, typeId); + if (type == null) { + throw new CmisObjectNotFoundException("Type '" + typeId + + "' is unknown!"); + } + + String objectId = null; + // TODO ACE can be set ! + if (type.getBaseTypeId() == BaseTypeId.CMIS_DOCUMENT) { + objectId = createDocument(callContext, repositoryId, properties, + folderId, contentStream, versioningState, null, null, null); + } else if (type.getBaseTypeId() == BaseTypeId.CMIS_FOLDER) { + objectId = createFolder(callContext, repositoryId, properties, + folderId, policies, null, null, extension); + } else if (type.getBaseTypeId() == BaseTypeId.CMIS_RELATIONSHIP) { + objectId = createRelationship(callContext, repositoryId, properties, + policies, null, null, extension); + } else if (type.getBaseTypeId() == BaseTypeId.CMIS_POLICY) { + objectId = createPolicy(callContext, repositoryId, properties, folderId, + policies, null, null, extension); + } else if (type.getBaseTypeId() == BaseTypeId.CMIS_ITEM) { + objectId = createItem(callContext, repositoryId, properties, folderId, + policies, null, null, extension); + } else { + throw new CmisObjectNotFoundException( + "Cannot create object of type '" + typeId + "'!"); + } + + log.debug(String.format("[Repository=%s][ObjectId=%s][FileName=%s]Creating object data by compileService ...",repositoryId, objectId, contentStream.getFileName())); + ObjectData object = compileService.compileObjectData(callContext, + repositoryId, contentService.getContent(repositoryId, objectId), null, + false, IncludeRelationships.NONE, null, false); + log.debug(String.format("[Repository=%s][ObjectId=%s][FileName=%s]Create object data by compileService successfully.",repositoryId, objectId, contentStream.getFileName())); + + return object; + } + + @Override + public String createFolder(CallContext callContext, String repositoryId, + Properties properties, String folderId, List policies, + Acl addAces, Acl removeAces, ExtensionsData extension) { + FolderTypeDefinition td = (FolderTypeDefinition) typeManager + .getTypeDefinition(repositoryId, DataUtil.getObjectTypeId(properties)); + Folder parentFolder = contentService.getFolder(repositoryId, folderId); + + // ////////////////// + // General Exception + // ////////////////// + exceptionService.objectNotFoundParentFolder(repositoryId, folderId, parentFolder); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_CREATE_FOLDER_FOLDER, parentFolder); + + // ////////////////// + // Specific Exception + // ////////////////// + exceptionService.constraintBaseTypeId(repositoryId, + properties, BaseTypeId.CMIS_FOLDER); + exceptionService.constraintAllowedChildObjectTypeId(parentFolder, + properties); + exceptionService.constraintPropertyValue(repositoryId, td, + properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); + exceptionService + .constraintCotrollablePolicies(td, policies, properties); + exceptionService.constraintCotrollableAcl(td, addAces, removeAces, + properties); + exceptionService.constraintPermissionDefined(repositoryId, addAces, null); + exceptionService.constraintPermissionDefined(repositoryId, removeAces, null); + exceptionService.nameConstraintViolation(properties, parentFolder); + + // ////////////////// + // Body of the method + // ////////////////// + Folder folder = contentService.createFolder(callContext, repositoryId, + properties, parentFolder); + return folder.getId(); + } + + @Override + public String createDocument(CallContext callContext, + String repositoryId, Properties properties, + String folderId, ContentStream contentStream, + VersioningState versioningState, List policies, Acl addAces, Acl removeAces) { + String objectTypeId = DataUtil.getIdProperty(properties, + PropertyIds.OBJECT_TYPE_ID); + DocumentTypeDefinition td = (DocumentTypeDefinition) typeManager + .getTypeDefinition(repositoryId, objectTypeId); + Folder parentFolder = contentService.getFolder(repositoryId, folderId); + + // ////////////////// + // General Exception + // ////////////////// + exceptionService.invalidArgumentRequired("properties", properties); + exceptionService.invalidArgumentRequiredParentFolderId(repositoryId, folderId); + exceptionService.objectNotFoundParentFolder(repositoryId, folderId, parentFolder); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_CREATE_FOLDER_FOLDER, parentFolder); + + // ////////////////// + // Specific Exception + // ////////////////// + exceptionService.constraintBaseTypeId(repositoryId, + properties, BaseTypeId.CMIS_DOCUMENT); + exceptionService.constraintAllowedChildObjectTypeId(parentFolder, + properties); + exceptionService.constraintPropertyValue(repositoryId, td, + properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); + exceptionService.constraintContentStreamRequired(td, contentStream); + exceptionService.constraintControllableVersionable(td, versioningState, + null); + versioningState = (td.isVersionable() && versioningState == null) ? VersioningState.MAJOR : versioningState; + exceptionService + .constraintCotrollablePolicies(td, policies, properties); + exceptionService.constraintCotrollableAcl(td, addAces, removeAces, + properties); + exceptionService.constraintPermissionDefined(repositoryId, addAces, null); + exceptionService.constraintPermissionDefined(repositoryId, removeAces, null); + exceptionService.streamNotSupported(td, contentStream); + exceptionService.nameConstraintViolation(properties, parentFolder); + + // ////////////////// + // Body of the method + // ////////////////// + Document document = contentService.createDocument(callContext, + repositoryId, properties, parentFolder, contentStream, versioningState, null); + return document.getId(); + } + + @Override + public String createDocumentFromSource(CallContext callContext, + String repositoryId, String sourceId, Properties properties, + String folderId, VersioningState versioningState, + List policies, Acl addAces, Acl removeAces) { + Document original = contentService.getDocument(repositoryId, sourceId); + DocumentTypeDefinition td = (DocumentTypeDefinition) typeManager + .getTypeDefinition(repositoryId, original.getObjectType()); + + // ////////////////// + // General Exception + // ////////////////// + exceptionService.invalidArgumentRequired("properties", properties); + exceptionService.invalidArgumentRequiredParentFolderId(repositoryId, folderId); + Folder parentFolder = contentService.getFolder(repositoryId, folderId); + exceptionService.objectNotFoundParentFolder(repositoryId, folderId, parentFolder); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_CREATE_FOLDER_FOLDER, parentFolder); + + // ////////////////// + // Specific Exception + // ////////////////// + exceptionService.constraintBaseTypeId(repositoryId, + properties, BaseTypeId.CMIS_DOCUMENT); + exceptionService.constraintAllowedChildObjectTypeId(parentFolder, + properties); + exceptionService.constraintPropertyValue(repositoryId, td, + properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); + exceptionService.constraintControllableVersionable(td, versioningState, + null); + versioningState = (td.isVersionable() && versioningState == null) ? VersioningState.MAJOR : versioningState; + exceptionService + .constraintCotrollablePolicies(td, policies, properties); + exceptionService.constraintCotrollableAcl(td, addAces, removeAces, + properties); + exceptionService.constraintPermissionDefined(repositoryId, addAces, null); + exceptionService.constraintPermissionDefined(repositoryId, removeAces, null); + exceptionService.nameConstraintViolation(properties, parentFolder); + + // ////////////////// + // Body of the method + // ////////////////// + Document document = contentService.createDocumentFromSource( + callContext, repositoryId, properties, parentFolder, + original, versioningState, policies, addAces, removeAces); + return document.getId(); + } + + @Override + public void setContentStream(CallContext callContext, + String repositoryId, Holder objectId, + boolean overwriteFlag, ContentStream contentStream, Holder changeToken) { + // ////////////////// + // General Exception + // ////////////////// + String id = objectId.getValue(); + + exceptionService.invalidArgumentRequiredString("objectId", id); + exceptionService + .invalidArgumentRequired("contentStream", contentStream); + Document doc = (Document) contentService.getContent(repositoryId, id); + exceptionService.objectNotFound(DomainType.OBJECT, doc, id); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_SET_CONTENT_DOCUMENT, doc); + DocumentTypeDefinition td = (DocumentTypeDefinition) typeManager + .getTypeDefinition(repositoryId, doc.getObjectType()); + exceptionService.constraintImmutable(repositoryId, doc, td); + + // ////////////////// + // Specific Exception + // ////////////////// + exceptionService.contentAlreadyExists(doc, overwriteFlag); + exceptionService.streamNotSupported(td, contentStream); + exceptionService.updateConflict(doc, changeToken); + exceptionService.versioning(doc); + Folder parent = contentService.getParent(repositoryId, id); + exceptionService.objectNotFoundParentFolder(repositoryId, id, parent); + + // ////////////////// + // Body of the method + // ////////////////// + String oldId = objectId.getValue(); + + // TODO Externalize versioningState + if(doc.isPrivateWorkingCopy()){ + Document result = contentService.replacePwc(callContext, repositoryId, + doc, contentStream); + objectId.setValue(result.getId()); + }else{ + Document result = contentService.createDocumentWithNewStream(callContext, repositoryId, + doc, contentStream); + objectId.setValue(result.getId()); + } + + nemakiCachePool.get(repositoryId).removeCmisCache(oldId); + } + + @Override + public void deleteContentStream(CallContext callContext, + String repositoryId, Holder objectId, + Holder changeToken, ExtensionsData extension) { + // ////////////////// + // Exception + // ////////////////// + exceptionService.invalidArgumentRequiredHolderString("objectId", + objectId); + Document document = contentService.getDocument(repositoryId, objectId.getValue()); + exceptionService.objectNotFound(DomainType.OBJECT, document, + document.getId()); + exceptionService.constraintContentStreamRequired(repositoryId, document); + + // ////////////////// + // Body of the method + // ////////////////// + contentService.deleteContentStream(callContext, repositoryId, objectId); + + nemakiCachePool.get(repositoryId).removeCmisCache(objectId.getValue()); + } + + @Override + public void appendContentStream(CallContext callContext, + String repositoryId, Holder objectId, + Holder changeToken, ContentStream contentStream, + boolean isLastChunk, ExtensionsData extension) { + // ////////////////// + // General Exception + // ////////////////// + String id = objectId.getValue(); + + exceptionService.invalidArgumentRequiredString("objectId", id); + exceptionService + .invalidArgumentRequired("contentStream", contentStream); + Document doc = (Document) contentService.getContent(repositoryId, id); + exceptionService.objectNotFound(DomainType.OBJECT, doc, id); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_SET_CONTENT_DOCUMENT, doc); + DocumentTypeDefinition td = (DocumentTypeDefinition) typeManager + .getTypeDefinition(repositoryId, doc.getObjectType()); + exceptionService.constraintImmutable(repositoryId, doc, td); + + // ////////////////// + // Specific Exception + // ////////////////// + exceptionService.streamNotSupported(td, contentStream); + exceptionService.updateConflict(doc, changeToken); + exceptionService.versioning(doc); + + // ////////////////// + // Body of the method + // ////////////////// + contentService.appendAttachment(callContext, repositoryId, objectId, + changeToken, contentStream, isLastChunk, extension); + + nemakiCachePool.get(repositoryId).removeCmisCache(objectId.getValue()); + } + + @Override + public String createRelationship(CallContext callContext, + String repositoryId, Properties properties, List policies, + Acl addAces, Acl removeAces, ExtensionsData extension) { + String objectTypeId = DataUtil.getIdProperty(properties, + PropertyIds.OBJECT_TYPE_ID); + RelationshipTypeDefinition td = (RelationshipTypeDefinition) typeManager + .getTypeDefinition(repositoryId, objectTypeId); + // ////////////////// + // Exception + // ////////////////// + exceptionService.invalidArgumentRequiredCollection("properties", + properties.getPropertyList()); + String sourceId = DataUtil.getIdProperty(properties, + PropertyIds.SOURCE_ID); + if (sourceId != null) { + Content source = contentService.getContent(repositoryId, DataUtil + .getStringProperty(properties, PropertyIds.SOURCE_ID)); + if (source == null) + exceptionService.constraintAllowedSourceTypes(td, source); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_CREATE_RELATIONSHIP_SOURCE, source); + } + String targetId = DataUtil.getIdProperty(properties, + PropertyIds.TARGET_ID); + if (targetId != null) { + Content target = contentService.getContent(repositoryId, DataUtil + .getStringProperty(properties, PropertyIds.TARGET_ID)); + if (target == null) + exceptionService.constraintAllowedTargetTypes(td, target); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_CREATE_RELATIONSHIP_TARGET, target); + } + + exceptionService.constraintBaseTypeId(repositoryId, + properties, BaseTypeId.CMIS_RELATIONSHIP); + exceptionService.constraintPropertyValue(repositoryId, td, + properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); + exceptionService + .constraintCotrollablePolicies(td, policies, properties); + exceptionService.constraintCotrollableAcl(td, addAces, removeAces, + properties); + exceptionService.constraintPermissionDefined(repositoryId, addAces, null); + exceptionService.constraintPermissionDefined(repositoryId, removeAces, null); + exceptionService.nameConstraintViolation(properties, null); + + // ////////////////// + // Body of the method + // ////////////////// + Relationship relationship = contentService.createRelationship( + callContext, repositoryId, properties, policies, addAces, + removeAces, extension); + nemakiCachePool.get(repositoryId).removeCmisCache(relationship.getSourceId()); + nemakiCachePool.get(repositoryId).removeCmisCache(relationship.getTargetId()); + + return relationship.getId(); + } + + @Override + public String createPolicy(CallContext callContext, String repositoryId, + Properties properties, String folderId, List policies, + Acl addAces, Acl removeAces, ExtensionsData extension) { + // ////////////////// + // General Exception + // ////////////////// + exceptionService.invalidArgumentRequiredCollection("properties", + properties.getPropertyList()); + // NOTE: folderId is ignored because policy is not filable in Nemaki + TypeDefinition td = typeManager.getTypeDefinition(repositoryId, DataUtil + .getIdProperty(properties, PropertyIds.OBJECT_TYPE_ID)); + exceptionService.constraintPropertyValue(repositoryId, td, + properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); + + // ////////////////// + // Specific Exception + // ////////////////// + exceptionService.constraintBaseTypeId(repositoryId, + properties, BaseTypeId.CMIS_POLICY); + // exceptionService.constraintAllowedChildObjectTypeId(parent, + // properties); + exceptionService + .constraintCotrollablePolicies(td, policies, properties); + exceptionService.constraintCotrollableAcl(td, addAces, removeAces, + properties); + // exceptionService.nameConstraintViolation(properties, parent); + + // ////////////////// + // Body of the method + // ////////////////// + Policy policy = contentService.createPolicy(callContext, repositoryId, + properties, policies, addAces, removeAces, extension); + return policy.getId(); + } + + @Override + public String createItem(CallContext callContext, String repositoryId, + Properties properties, String folderId, List policies, + Acl addAces, Acl removeAces, ExtensionsData extension) { + // ////////////////// + // General Exception + // ////////////////// + TypeDefinition td = typeManager.getTypeDefinition(repositoryId, DataUtil + .getObjectTypeId(properties)); + Folder parentFolder = contentService.getFolder(repositoryId, folderId); + exceptionService.objectNotFoundParentFolder(repositoryId, folderId, parentFolder); + exceptionService.invalidArgumentRequiredCollection("properties", + properties.getPropertyList()); + + // ////////////////// + // Specific Exception + // ////////////////// + exceptionService.constraintBaseTypeId(repositoryId, properties, BaseTypeId.CMIS_ITEM); + exceptionService.constraintPropertyValue(repositoryId, td, + properties, DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID)); + exceptionService + .constraintCotrollablePolicies(td, policies, properties); + exceptionService.constraintCotrollableAcl(td, addAces, removeAces, + properties); + + // ////////////////// + // Body of the method + // ////////////////// + Item item = contentService.createItem(callContext, repositoryId, + properties, folderId, policies, addAces, removeAces, extension); + return item.getId(); + } + + @Override + public void updateProperties(CallContext callContext, + String repositoryId, Holder objectId, + Properties properties, Holder changeToken) { + + // ////////////////// + // Exception + // ////////////////// + Content content = checkExceptionBeforeUpdateProperties(callContext, + repositoryId, objectId, properties, changeToken); + + // ////////////////// + // Body of the method + // ////////////////// + String id = objectId.getValue(); + + contentService.updateProperties(callContext, repositoryId, properties, content); + + nemakiCachePool.get(repositoryId).removeCmisCache(id); + } + + private Content checkExceptionBeforeUpdateProperties( + CallContext callContext, String repositoryId, + Holder objectId, Properties properties, Holder changeToken) { + // ////////////////// + // General Exception + // ////////////////// + exceptionService.invalidArgumentRequiredHolderString("objectId", + objectId); + exceptionService.invalidArgumentRequiredCollection("properties", + properties.getPropertyList()); + Content content = contentService.getContent(repositoryId, objectId.getValue()); + exceptionService.objectNotFound(DomainType.OBJECT, content, + objectId.getValue()); + if (content.isDocument()) { + Document d = (Document) content; + exceptionService.versioning(d); + exceptionService.constraintUpdateWhenCheckedOut(repositoryId, callContext.getUsername(), d); + TypeDefinition typeDef = typeManager.getTypeDefinition(repositoryId, d); + exceptionService.constraintImmutable(repositoryId, d, typeDef); + } + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_UPDATE_PROPERTIES_OBJECT, content); + exceptionService.updateConflict(content, changeToken); + + + + TypeDefinition tdf = typeManager.getTypeDefinition(repositoryId, content); + exceptionService.constraintPropertyValue(repositoryId, tdf, + properties, objectId.getValue()); + + return content; + } + + @Override + public List bulkUpdateProperties( + CallContext callContext, + String repositoryId, + List objectIdAndChangeToken, Properties properties, + List addSecondaryTypeIds, List removeSecondaryTypeIds, ExtensionsData extension) { + // ////////////////// + // General Exception + // ////////////////// + // Each permission is checked at each execution + exceptionService.invalidArgumentRequiredCollection( + "objectIdAndChangeToken", objectIdAndChangeToken); + exceptionService.invalidArgumentSecondaryTypeIds(repositoryId, properties); + + // ////////////////// + // Body of the method + // ////////////////// + List results = new ArrayList(); + + for (BulkUpdateObjectIdAndChangeToken idAndToken : objectIdAndChangeToken) { + try { + Content content = checkExceptionBeforeUpdateProperties( + callContext, repositoryId, + new Holder(idAndToken.getId()), + properties, new Holder(idAndToken.getChangeToken())); + contentService.updateProperties(callContext, repositoryId, + properties, content); + nemakiCachePool.get(repositoryId).removeCmisCache(content.getId()); + + BulkUpdateObjectIdAndChangeToken result = new BulkUpdateObjectIdAndChangeTokenImpl( + idAndToken.getId(), content.getId(), + String.valueOf(content.getChangeToken())); + results.add(result); + } catch (Exception e) { + // Don't throw an error + // Don't return any BulkUpdateObjectIdAndChangetoken + } + } + + return results; + } + + @Override + public void moveObject(CallContext callContext, String repositoryId, + Holder objectId, String sourceFolderId, String targetFolderId) { + // ////////////////// + // General Exception + // ////////////////// + exceptionService.invalidArgumentRequiredHolderString("objectId", + objectId); + exceptionService.invalidArgumentRequiredString("sourceFolderId", + sourceFolderId); + exceptionService.invalidArgumentRequiredString("targetFolderId", + targetFolderId); + Content content = contentService.getContent(repositoryId, objectId.getValue()); + exceptionService.objectNotFound(DomainType.OBJECT, content, + objectId.getValue()); + Folder source = contentService.getFolder(repositoryId, sourceFolderId); + exceptionService.objectNotFound(DomainType.OBJECT, source, + sourceFolderId); + Folder target = contentService.getFolder(repositoryId, targetFolderId); + exceptionService.objectNotFound(DomainType.OBJECT, target, + targetFolderId); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_MOVE_OBJECT, content); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_MOVE_SOURCE, source); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_MOVE_TARGET, target); + + // ////////////////// + // Body of the method + // ////////////////// + contentService.move(repositoryId, content, target); + + nemakiCachePool.get(repositoryId).removeCmisCache(content.getId()); + } + + private void deleteObjectInternal(CallContext callContext, String repositoryId, + String objectId, Boolean allVersions, Boolean deleteWithParent) { + // ////////////////// + // General Exception + // ////////////////// + exceptionService.invalidArgumentRequiredString("objectId", objectId); + Content content = contentService.getContent(repositoryId, objectId); + exceptionService.objectNotFound(DomainType.OBJECT, content, objectId); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_DELETE_OBJECT, content); + exceptionService.constraintDeleteRootFolder(repositoryId, objectId); + + // ////////////////// + // Body of the method + // ////////////////// + if (content.isDocument()) { + contentService.deleteDocument(callContext, repositoryId, + content.getId(), allVersions, deleteWithParent); + } else if (content.isFolder()) { + List children = contentService.getChildren(repositoryId, objectId); + if (!CollectionUtils.isEmpty(children)) { + exceptionService + .constraint(objectId, + "deleteObject method is invoked on a folder containing objects."); + } + contentService.delete(callContext, repositoryId, objectId, deleteWithParent); + + } else { + contentService.delete(callContext, repositoryId, objectId, deleteWithParent); + } + + nemakiCachePool.get(repositoryId).removeCmisCache(content.getId()); + } + + @Override + public void deleteObject(CallContext callContext, String repositoryId, + String objectId, Boolean allVersions) { + deleteObjectInternal(callContext, repositoryId, objectId, allVersions, false); + } + + @Override + public FailedToDeleteData deleteTree(CallContext callContext, + String repositoryId, String folderId, Boolean allVersions, + UnfileObject unfileObjects, Boolean continueOnFailure, ExtensionsData extension) { + // ////////////////// + // General Exception + // ////////////////// + exceptionService.invalidArgumentRequiredString("objectId", folderId); + Folder folder = contentService.getFolder(repositoryId, folderId); + exceptionService.permissionDenied(callContext, + repositoryId, PermissionMapping.CAN_DELETE_TREE_FOLDER, folder); + exceptionService.constraintDeleteRootFolder(repositoryId, folderId); + + // ////////////////// + // Specific Exception + // ////////////////// + if (folder == null) + exceptionService.constraint(folderId, + "deleteTree cannot be invoked on a non-folder object"); + + // ////////////////// + // Body of the method + // ////////////////// + // Delete descendants + List failureIds = new ArrayList(); + + List children = contentService.getChildren(repositoryId, folderId); + if (!CollectionUtils.isEmpty(children)) { + for (Content child : children) { + try { + if (child.isFolder()) { + deleteTree(callContext, repositoryId, child.getId(), allVersions, + unfileObjects, continueOnFailure, extension); + } else { + deleteObjectInternal(callContext, repositoryId, child.getId(), allVersions, true); + } + } catch (Exception e) { + StringBuilder sb = new StringBuilder(); + sb.append("objectId:").append(child.getId()).append(" failed to be deleted."); + + if (continueOnFailure) { + failureIds.add(child.getId()); + log.warn(sb.toString(), e); + continue; + } else { + log.error(sb.toString(), e); + } + } + } + } + + // Delete the folder itself + try { + deleteObjectInternal(callContext, repositoryId, folderId, allVersions, false); + } catch (Exception e) { + StringBuilder sb = new StringBuilder(); + sb.append("objectId:").append(folderId).append(" failed to be deleted."); + + if (continueOnFailure) { + failureIds.add(folderId); + log.warn(sb.toString(), e); + } else { + log.error(sb.toString(), e); + } + } + + /*failureIds = contentService.deleteTree(callContext, folderId, allVersions, + continueOnFailure, false);*/ + solrUtil.callSolrIndexing(repositoryId); + + // Check FailedToDeleteData + // FIXME Consider orphans that was failed to be deleted + FailedToDeleteDataImpl fdd = new FailedToDeleteDataImpl(); + + if (CollectionUtils.isNotEmpty(failureIds)) { + fdd.setIds(failureIds); + } else { + fdd.setIds(new ArrayList()); + } + return fdd; + } + + public void setContentService(ContentService contentService) { + this.contentService = contentService; + } + + public void setExceptionService(ExceptionService exceptionService) { + this.exceptionService = exceptionService; + } + + public void setCompileService(CompileService compileService) { + this.compileService = compileService; + } + + public void setTypeManager(TypeManager typeManager) { + this.typeManager = typeManager; + } + + public void setSolrUtil(SolrUtil solrUtil) { + this.solrUtil = solrUtil; + } + + public void setNemakiCachePool(NemakiCachePool nemakiCachePool) { + this.nemakiCachePool = nemakiCachePool; + } +} diff --git a/core/src/main/webapp/WEB-INF/classes/log4j.xml b/core/src/main/webapp/WEB-INF/classes/log4j.xml index 7d930ab0..64998c51 100644 --- a/core/src/main/webapp/WEB-INF/classes/log4j.xml +++ b/core/src/main/webapp/WEB-INF/classes/log4j.xml @@ -11,7 +11,7 @@ - + From 9412cfa341ee4a016693f6b18d2dced5eeb7515d Mon Sep 17 00:00:00 2001 From: git -v Date: Tue, 5 Jan 2016 21:44:17 +0900 Subject: [PATCH 12/20] Modify : Log message modified --- .../businesslogic/impl/ContentServiceImpl.java | 3 --- .../cmis/aspect/impl/PermissionServiceImpl.java | 12 ------------ .../nemaki/cmis/factory/CmisServiceFactory.java | 4 ---- .../nemaki/cmis/service/impl/ObjectServiceImpl.java | 2 -- 4 files changed, 21 deletions(-) diff --git a/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java index 04d7c87c..6a692b1f 100644 --- a/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java @@ -447,7 +447,6 @@ public Document createDocument(CallContext callContext, String repositoryId, Pro // Create Document document = contentDaoService.create(repositoryId, d); - log.debug(String.format("[Repository=%s][DocumentId=%s][FileName=%s]Create entry on couchdb successfully.",repositoryId, document.getId(), contentStream.getFileName())); // Update versionSeriesId#versionSeriesCheckedOutId after creating a PWC if (versioningState == VersioningState.CHECKEDOUT) { @@ -456,8 +455,6 @@ public Document createDocument(CallContext callContext, String repositoryId, Pro // Write change event writeChangeEvent(callContext, repositoryId, document, ChangeType.CREATED); - log.debug(String.format("[Repository=%s][DocumentId=%s][FileName=%s]Write change event successfully.",repositoryId, document.getId(), contentStream.getFileName())); - // Call Solr indexing(optional) solrUtil.callSolrIndexing(repositoryId); diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java index 6c7b3657..5f71e7d6 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/aspect/impl/PermissionServiceImpl.java @@ -103,15 +103,7 @@ public Boolean checkPermission(CallContext callContext, String repositoryId, Str String userName = callContext.getUsername(); User u = principalService.getUserById(repositoryId, userName); - /* - CallContextImpl cci = (CallContextImpl) callContext; - Boolean _isAdmin = (Boolean) cci.get(CallContextKey.IS_ADMIN); - boolean isAdmin = (_isAdmin == null) ? false : _isAdmin; - */ - - if (u != null & u.isAdmin()) { - log.debug(String.format("[Repository=%s][FileName=%s][User=%s][Permission=true] is_admin? => %s" ,repositoryId, content.getName(), callContext.getUsername(), u.isAdmin())); return true; } @@ -122,7 +114,6 @@ public Boolean checkPermission(CallContext callContext, String repositoryId, Str if(document.isPrivateWorkingCopy()){ VersionSeries vs = contentService.getVersionSeries(repositoryId, document); if(!callContext.getUsername().equals(vs.getVersionSeriesCheckedOutBy())){ - log.debug(String.format("[Repository=%s][FileName=%s][User=%s][Permission=false] PWS correct user => %s ",repositoryId, content.getName(),callContext.getUsername(), vs.getVersionSeriesCheckedOutBy())); return false; } } @@ -136,13 +127,11 @@ public Boolean checkPermission(CallContext callContext, String repositoryId, Str Relationship relationship = (Relationship)content; boolean hasRelationshipPermission = checkRelationshipPermission(callContext, repositoryId, key, relationship); - log.debug(String.format("[Repository=%s][FileName=%s][User=%s][Permission=%s] Is relationship. ",repositoryId, content.getName(), callContext.getUsername(),hasRelationshipPermission)); return hasRelationshipPermission; } // Void Acl fails(but Admin can do an action) if (acl == null){ - log.debug(String.format("[Repository=%s][FileName=%s][User=%s][Permission=false] No Acl! ",repositoryId, content.getName(), callContext.getUsername())); return false; } @@ -170,7 +159,6 @@ public Boolean checkPermission(CallContext callContext, String repositoryId, Str // Check mapping between the user and the content boolean calcPermission = checkCalculatedPermissions(repositoryId, key, userPermissions); - log.debug(String.format("[Repository=%s][FileName=%s][User=%s][Permission=%s] Check Mapping. ",repositoryId, content.getName(), callContext.getUsername(), calcPermission)); return calcPermission; } diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java b/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java index 9eeae09d..a93de161 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java @@ -68,9 +68,6 @@ public org.apache.chemistry.opencmis.commons.server.CmisService getService(CallC if (auth) { - String msg = String.format("[Repository=%1$s][userName=%2$s]Authentication succeeded",repositryId, userName); - log.info(msg); - // Create CmisService CmisServiceWrapper wrapper = new CmisServiceWrapper( cmisService, @@ -80,7 +77,6 @@ public org.apache.chemistry.opencmis.commons.server.CmisService getService(CallC return wrapper; } else { - String msg = String.format("[Repository=%1$s][UserName=%2$s]Authentication failed",repositryId, userName); throw new CmisUnauthorizedException(msg, BigInteger.valueOf(401)); } } diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java index 67de0599..dfcbef97 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/service/impl/ObjectServiceImpl.java @@ -287,11 +287,9 @@ public ObjectData create(CallContext callContext, String repositoryId, "Cannot create object of type '" + typeId + "'!"); } - log.debug(String.format("[Repository=%s][ObjectId=%s][FileName=%s]Creating object data by compileService ...",repositoryId, objectId, contentStream.getFileName())); ObjectData object = compileService.compileObjectData(callContext, repositoryId, contentService.getContent(repositoryId, objectId), null, false, IncludeRelationships.NONE, null, false); - log.debug(String.format("[Repository=%s][ObjectId=%s][FileName=%s]Create object data by compileService successfully.",repositoryId, objectId, contentStream.getFileName())); return object; } From 996b8cf9a1d397375380458ff08c87b83b18660b Mon Sep 17 00:00:00 2001 From: git -v Date: Tue, 5 Jan 2016 21:52:16 +0900 Subject: [PATCH 13/20] Fix : Fix msg missing --- .../java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java b/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java index a93de161..00bea280 100644 --- a/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java +++ b/core/src/main/java/jp/aegif/nemaki/cmis/factory/CmisServiceFactory.java @@ -77,6 +77,7 @@ public org.apache.chemistry.opencmis.commons.server.CmisService getService(CallC return wrapper; } else { + String msg = String.format("[Repository=%1$s][UserName=%2$s]Authentication failed",repositryId, userName); throw new CmisUnauthorizedException(msg, BigInteger.valueOf(401)); } } From 77e903929e5daa202defb87073f3f5bb0df2cb11 Mon Sep 17 00:00:00 2001 From: linzhixing Date: Wed, 6 Jan 2016 00:54:31 +0900 Subject: [PATCH 14/20] Fix pasing database result of isAdmin #179 --- core/src/main/java/jp/aegif/nemaki/rest/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/jp/aegif/nemaki/rest/UserResource.java b/core/src/main/java/jp/aegif/nemaki/rest/UserResource.java index 7149ec93..efd59624 100644 --- a/core/src/main/java/jp/aegif/nemaki/rest/UserResource.java +++ b/core/src/main/java/jp/aegif/nemaki/rest/UserResource.java @@ -466,7 +466,7 @@ private JSONObject convertUserToJson(User user) { userJSON.put(ITEM_MODIFIER, user.getModifier()); userJSON.put(ITEM_MODIFIED, modified); - boolean isAdmin = (user.isAdmin() == null) ? false : true; + boolean isAdmin = (user.isAdmin() == null) ? false : user.isAdmin(); userJSON.put(ITEM_IS_ADMIN, isAdmin); JSONArray jfs = new JSONArray(); From d3fbabe01989db96399f4fc34eb7c18efd3a7a5e Mon Sep 17 00:00:00 2001 From: linzhixing Date: Wed, 6 Jan 2016 11:14:52 +0900 Subject: [PATCH 15/20] Replace log4j.xml to log4j-aws.xml Current log4j.xml is overwritten for AWS. --- .../main/webapp/WEB-INF/classes/log4j-aws.xml | 24 ++++++++++++++ .../src/main/webapp/WEB-INF/classes/log4j.xml | 32 ++++++++++++++----- 2 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 core/src/main/webapp/WEB-INF/classes/log4j-aws.xml diff --git a/core/src/main/webapp/WEB-INF/classes/log4j-aws.xml b/core/src/main/webapp/WEB-INF/classes/log4j-aws.xml new file mode 100644 index 00000000..64998c51 --- /dev/null +++ b/core/src/main/webapp/WEB-INF/classes/log4j-aws.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/src/main/webapp/WEB-INF/classes/log4j.xml b/core/src/main/webapp/WEB-INF/classes/log4j.xml index 64998c51..0e4e8b78 100644 --- a/core/src/main/webapp/WEB-INF/classes/log4j.xml +++ b/core/src/main/webapp/WEB-INF/classes/log4j.xml @@ -2,23 +2,39 @@ - - + + + + + + + + + + + + + + + + + - - - + + + + - - + - \ No newline at end of file From 68fe3f1857cddc4740928a0568f8be5b4a1462e0 Mon Sep 17 00:00:00 2001 From: linzhixing Date: Thu, 7 Jan 2016 02:00:02 +0900 Subject: [PATCH 16/20] Add custom string parser for logging --- .../spring/aspect/log/CustomToString.java | 5 + .../aspect/{ => log}/DefaultLogger.java | 35 +++--- .../aspect/log/impl/CustomToStringImpl.java | 117 ++++++++++++++++++ .../webapp/WEB-INF/classes/aopContext.xml | 7 ++ .../src/main/webapp/WEB-INF/classes/log4j.xml | 2 + .../WEB-INF/classes/nemakiware.properties | 2 +- 6 files changed, 153 insertions(+), 15 deletions(-) create mode 100644 core/src/main/java/jp/aegif/nemaki/util/spring/aspect/log/CustomToString.java rename core/src/main/java/jp/aegif/nemaki/util/spring/aspect/{ => log}/DefaultLogger.java (77%) create mode 100644 core/src/main/java/jp/aegif/nemaki/util/spring/aspect/log/impl/CustomToStringImpl.java diff --git a/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/log/CustomToString.java b/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/log/CustomToString.java new file mode 100644 index 00000000..2f20bf35 --- /dev/null +++ b/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/log/CustomToString.java @@ -0,0 +1,5 @@ +package jp.aegif.nemaki.util.spring.aspect.log; + +public interface CustomToString { + +} diff --git a/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/DefaultLogger.java b/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/log/DefaultLogger.java similarity index 77% rename from core/src/main/java/jp/aegif/nemaki/util/spring/aspect/DefaultLogger.java rename to core/src/main/java/jp/aegif/nemaki/util/spring/aspect/log/DefaultLogger.java index be6e086a..3d383ab0 100644 --- a/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/DefaultLogger.java +++ b/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/log/DefaultLogger.java @@ -1,16 +1,14 @@ -package jp.aegif.nemaki.util.spring.aspect; - -import java.util.Arrays; +package jp.aegif.nemaki.util.spring.aspect.log; import javax.annotation.PostConstruct; import org.apache.chemistry.opencmis.commons.server.CallContext; -import org.apache.log4j.Appender; import org.apache.log4j.Level; import org.apache.log4j.Logger; -import org.apache.log4j.xml.DOMConfigurator; import org.aspectj.lang.ProceedingJoinPoint; +import jp.aegif.nemaki.util.spring.aspect.log.impl.CustomToStringImpl; + public class DefaultLogger { private static Logger log = Logger.getLogger(DefaultLogger.class); @@ -21,6 +19,8 @@ public class DefaultLogger { private boolean beforeEnabled; private boolean afterEnabled; private boolean callContextEnabled; + + private CustomToStringImpl customToString; @PostConstruct public void init() { @@ -38,10 +38,10 @@ public Object aroundMethod(ProceedingJoinPoint jp) throws Throwable{ if(callContextEnabled){ CallContext callContext = getCallContext(args); if(callContext == null){ - sb.append("N/A : "); + sb.append("N/A; "); }else{ String userId = callContext.getUsername(); - sb.append(userId + " : "); + sb.append("UserId=" + userId + " executes; "); } } @@ -53,12 +53,12 @@ public Object aroundMethod(ProceedingJoinPoint jp) throws Throwable{ } sb.append("#").append(jp.getSignature().getName()); if(arguments){ - sb.append(Arrays.asList(args)); + sb.append(customToString.parseList(args)); } //Before advice if(beforeEnabled){ - log.info(sb.toString()); + log.info("nemaki_log[BEFORE]; " + sb.append("; ").toString()); } //Execute method @@ -67,11 +67,13 @@ public Object aroundMethod(ProceedingJoinPoint jp) throws Throwable{ //After advice if(afterEnabled){ - sb.append(" returned "); - if (returnValue && result != null) - sb.append(result.toString()); - - log.info(sb.toString()); + sb.append("returned "); + if (returnValue && result != null){ + String resultString = customToString.parse(result); + sb.append(resultString); + } + + log.info("nemaki_log[AFTER]; " + sb.append("; ").toString()); } return result; @@ -121,4 +123,9 @@ public void setAfterEnabled(boolean afterEnabled) { public void setCallContextEnabled(boolean callContextEnabled) { this.callContextEnabled = callContextEnabled; } + + public void setCustomToString(CustomToStringImpl customToString) { + this.customToString = customToString; + } + } diff --git a/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/log/impl/CustomToStringImpl.java b/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/log/impl/CustomToStringImpl.java new file mode 100644 index 00000000..b174ee31 --- /dev/null +++ b/core/src/main/java/jp/aegif/nemaki/util/spring/aspect/log/impl/CustomToStringImpl.java @@ -0,0 +1,117 @@ +package jp.aegif.nemaki.util.spring.aspect.log.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.chemistry.opencmis.commons.PropertyIds; +import org.apache.chemistry.opencmis.commons.data.ObjectData; +import org.apache.chemistry.opencmis.commons.data.ObjectInFolderContainer; +import org.apache.chemistry.opencmis.commons.data.ObjectInFolderData; +import org.apache.chemistry.opencmis.commons.data.ObjectInFolderList; +import org.apache.chemistry.opencmis.commons.data.ObjectParentData; +import org.apache.chemistry.opencmis.commons.data.Properties; +import org.apache.chemistry.opencmis.commons.data.PropertyData; +import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderListImpl; +import org.apache.chemistry.opencmis.commons.server.CallContext; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class CustomToStringImpl { + public String parse(Object obj){ + if(obj == null){ + return "null"; + }else if(obj instanceof ObjectData){ + return parseObjectData((ObjectData)obj); + }else if(obj instanceof ObjectInFolderData){ + return parseObjectInFolderData((ObjectInFolderData)obj); + }else if(obj instanceof ObjectInFolderContainer){ + return parseObjectInFolderContainer((ObjectInFolderContainer)obj); + }else if(obj instanceof ObjectInFolderList){ + return parseObjectInFolderList((ObjectInFolderList)obj); + }else if(obj instanceof ObjectParentData){ + return parseObjectParentData((ObjectParentData)obj); + }else if(obj instanceof Properties){ + return parseProperties((Properties)obj); + }else{ + return obj.toString(); + } + } + + private String parseObjectData(ObjectData od){ + ObjectMapper mapper = new ObjectMapper(); + ObjectNode json = mapper.createObjectNode(); + json.put(PropertyIds.OBJECT_ID, od.getId()); + + Map>properties = od.getProperties().getProperties(); + convetPropertyToJson(json, PropertyIds.NAME, properties); + convetPropertyToJson(json, PropertyIds.OBJECT_TYPE_ID, properties); + + return json.toString(); + } + + private String parseObjectInFolderData(ObjectInFolderData oifd){ + ObjectData od = ((ObjectInFolderData)oifd).getObject(); + return parseObjectData(od); + } + + private String parseObjectInFolderContainer(ObjectInFolderContainer oifc){ + ObjectData od = ((ObjectInFolderContainer)oifc).getObject().getObject(); + return parseObjectData(od); + } + + private String parseObjectInFolderList(ObjectInFolderList list){ + List result = new ArrayList(); + Iterator itr = list.getObjects().iterator(); + while(itr.hasNext()){ + result.add(parseObjectInFolderData(itr.next())); + } + return result.toString(); + } + + private String parseObjectParentData(ObjectParentData opd){ + ObjectData od = ((ObjectParentData)opd).getObject(); + return parseObjectData(od); + } + + private String parseProperties(Properties properties){ + Map> map = properties.getProperties(); + Map_map = new HashMap(); + if(MapUtils.isNotEmpty(map)){ + for(Entry> e : map.entrySet()){ + Object values = e.getValue().getValues(); + _map.put(e.getKey(), values); + } + } + return _map.toString(); + } + + public String parseList(Object[] list){ + Listresult = new ArrayList(); + if(list == null){ + return null; + }else{ + for(int i=0; i> properties){ + PropertyData pd = properties.get(key); + if(pd != null && pd.getFirstValue() != null){ + json.put(key, pd.getFirstValue().toString()); + } + } +} diff --git a/core/src/main/webapp/WEB-INF/classes/aopContext.xml b/core/src/main/webapp/WEB-INF/classes/aopContext.xml index e2fcea46..0340a8eb 100644 --- a/core/src/main/webapp/WEB-INF/classes/aopContext.xml +++ b/core/src/main/webapp/WEB-INF/classes/aopContext.xml @@ -20,6 +20,13 @@ + + + + + + + \ No newline at end of file diff --git a/core/src/main/webapp/WEB-INF/classes/log4j.xml b/core/src/main/webapp/WEB-INF/classes/log4j.xml index 0e4e8b78..d1125989 100644 --- a/core/src/main/webapp/WEB-INF/classes/log4j.xml +++ b/core/src/main/webapp/WEB-INF/classes/log4j.xml @@ -35,6 +35,8 @@ + + \ No newline at end of file diff --git a/core/src/main/webapp/WEB-INF/classes/nemakiware.properties b/core/src/main/webapp/WEB-INF/classes/nemakiware.properties index ea8329b9..dc194068 100644 --- a/core/src/main/webapp/WEB-INF/classes/nemakiware.properties +++ b/core/src/main/webapp/WEB-INF/classes/nemakiware.properties @@ -55,7 +55,7 @@ rest.authtoken.enabled=true jodconverter.registry.dataformats=rendition-format.yml ###Logging -log.aspect.default=jp.aegif.nemaki.util.spring.aspect.DefaultLogger +log.aspect.default=jp.aegif.nemaki.util.spring.aspect.log.DefaultLogger log.aspect.expression=execution(* jp.aegif.nemaki.cmis.service..*Impl.*(..)) and !execution(* jp.aegif.nemaki.cmis.service.impl.RepositoryServiceImpl.*(..)) log.config.path=log4j.xml log.level=info From 147ef8e047f413c6b9339df376ed76dc1b4b93e9 Mon Sep 17 00:00:00 2001 From: linzhixing Date: Fri, 8 Jan 2016 17:11:07 +0900 Subject: [PATCH 17/20] Fix #180 duplicate name's suffix logic and Add the related CouchDB view --- .../impl/ContentServiceImpl.java | 88 ++++++------------- .../aegif/nemaki/dao/ContentDaoService.java | 8 ++ .../impl/cached/ContentDaoServiceImpl.java | 5 ++ .../dao/impl/couch/ContentDaoServiceImpl.java | 18 ++++ .../couchdb/initial_import/bedroom_init.dump | 43 ++++----- 5 files changed, 79 insertions(+), 83 deletions(-) diff --git a/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java index 6a692b1f..ad48cd4f 100644 --- a/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/businesslogic/impl/ContentServiceImpl.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.LinkedList; @@ -1148,7 +1149,7 @@ private void setUpdatePropertyValue(String repositoryId, Content content, Proper if (propertyData.getId().equals(PropertyIds.NAME)) { if (DataUtil.getIdProperty(properties, PropertyIds.OBJECT_ID) != content.getId()) { String uniqueName = buildUniqueName(repositoryId, DataUtil - .getStringProperty(properties, PropertyIds.NAME), content.getParentId(), content.getId()); + .getStringProperty(properties, PropertyIds.NAME), content.getParentId(), content); content.setName(uniqueName); } } @@ -1722,55 +1723,33 @@ private Boolean restorationTargetExists(String repositoryId, Archive archive) { // /////////////////////////////////////// // Utility // /////////////////////////////////////// - private String buildUniqueName(String repositoryId, String originalName, String folderId, String existingId) { + private String buildUniqueName(String repositoryId, String proposedName, String folderId, Content current) { boolean bun = propertyManager.readBoolean(PropertyKey.CAPABILITY_EXTENDED_BUILD_UNIQUE_NAME); if (!bun) { - return originalName; - } - - List children = getChildren(repositoryId, folderId); - - List conflicts = new ArrayList(); - if (CollectionUtils.isEmpty(children)) { - return originalName; - } else { - // Get collection of conflict names - for (Content child : children) { - // Exclude update of existing content in the folder - if (nameConflicts(originalName, child.getName())) { - if (!child.getId().equals(existingId)) { - conflicts.add(child.getName()); - } - } - } - - if (CollectionUtils.isEmpty(conflicts)) { - return originalName; - } else { - // Insert unused suffix - String nameWithSuffix = originalName; - for (int i = 0; i < conflicts.size() + 1; i++) { - nameWithSuffix = buildNameWithSuffix(originalName, i + 1); - if (!conflicts.contains(nameWithSuffix)) { - break; - } - } - return nameWithSuffix; + return proposedName; + } + + //Check if update method + if(current != null && current.getName().equals(proposedName)){ + return proposedName; + } + + Listnames = contentDaoService.getChildrenNames(repositoryId, folderId); + String[] splitted = splitFileName(proposedName); + String originalNameBody = splitted[0]; + String extension = splitted[1]; + + String newNameBody = originalNameBody; + for(Integer i = 1; i <= names.size(); i++){ + if(names.contains(newNameBody + extension)){ + newNameBody = originalNameBody + " ~" + i; + continue; + }else{ + break; } } - } - - private boolean nameConflicts(String originalName, String targetName) { - String[] original = splitFileName(originalName); - String[] target = splitFileName(targetName); - - if (!original[1].equals(target[1])) - return false; - if (removeCopySuffix(original[0]).equals(removeCopySuffix(target[0]))) { - return true; - } else { - return false; - } + + return newNameBody + extension; } private String[] splitFileName(String name) { @@ -1791,23 +1770,6 @@ private String[] splitFileName(String name) { return ary; } - private String buildNameWithSuffix(String fileName, int suffixNumber) { - String[] split = splitFileName(fileName); - String inserted = split[0] + "(" + suffixNumber + ")" + split[1]; - return inserted; - } - - private String removeCopySuffix(String bodyOfFileName) { - String regexp = "\\([0-9]+\\)$"; - Pattern pattern = Pattern.compile(regexp); - Matcher matcher = pattern.matcher(bodyOfFileName); - if (matcher.find()) { - return matcher.replaceFirst(""); - } else { - return bodyOfFileName; - } - } - private String increasedVersionLabel(Document document, VersioningState versioningState) { // e.g. #{major}(.{#minor}) String label = document.getVersionLabel(); diff --git a/core/src/main/java/jp/aegif/nemaki/dao/ContentDaoService.java b/core/src/main/java/jp/aegif/nemaki/dao/ContentDaoService.java index bb10f528..97ec084c 100644 --- a/core/src/main/java/jp/aegif/nemaki/dao/ContentDaoService.java +++ b/core/src/main/java/jp/aegif/nemaki/dao/ContentDaoService.java @@ -283,6 +283,14 @@ public interface ContentDaoService { */ Content getChildByName(String repositoryId, String parentId, String name); + /** + * Get children name index in a folder + * @param repositoryId + * @param parentId + * @return + */ + List getChildrenNames(String repositoryId, String parentId); + /** * Get a relationship * @param repositoryId TODO diff --git a/core/src/main/java/jp/aegif/nemaki/dao/impl/cached/ContentDaoServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/dao/impl/cached/ContentDaoServiceImpl.java index 1e8ac4b3..da2d0407 100644 --- a/core/src/main/java/jp/aegif/nemaki/dao/impl/cached/ContentDaoServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/dao/impl/cached/ContentDaoServiceImpl.java @@ -329,6 +329,11 @@ public Content getChildByName(String repositoryId, String parentId, String name) return nonCachedContentDaoService.getChildByName(repositoryId, parentId, name); } + @Override + public List getChildrenNames(String repositoryId, String parentId) { + return nonCachedContentDaoService.getChildrenNames(repositoryId, parentId); + } + @Override public Relationship getRelationship(String repositoryId, String objectId) { Cache cache = nemakiCachePool.get(repositoryId).getContentCache(); diff --git a/core/src/main/java/jp/aegif/nemaki/dao/impl/couch/ContentDaoServiceImpl.java b/core/src/main/java/jp/aegif/nemaki/dao/impl/couch/ContentDaoServiceImpl.java index 445d4f46..582ad188 100644 --- a/core/src/main/java/jp/aegif/nemaki/dao/impl/couch/ContentDaoServiceImpl.java +++ b/core/src/main/java/jp/aegif/nemaki/dao/impl/couch/ContentDaoServiceImpl.java @@ -475,6 +475,24 @@ public String getName() { return convertJsonToEachBaeType(result); } + public List getChildrenNames(String repositoryId, String parentId){ + ViewQuery query = new ViewQuery().designDocId(DESIGN_DOCUMENT).viewName("childrenNames") + .key(parentId); + ViewResult result = connectorPool.get(repositoryId).queryView(query); + + Listlist = new ArrayList(); + if(result == null || result.isEmpty()){ + return new ArrayList(); + }else{ + Iterator itr = result.iterator(); + while(itr.hasNext()){ + list.add(itr.next().getValue()); + } + } + + return list; + } + @Override public Relationship getRelationship(String repositoryId, String objectId) { CouchRelationship cr = connectorPool.get(repositoryId).get(CouchRelationship.class, objectId); diff --git a/setup/couchdb/initial_import/bedroom_init.dump b/setup/couchdb/initial_import/bedroom_init.dump index a0b364c5..b02d5cb9 100644 --- a/setup/couchdb/initial_import/bedroom_init.dump +++ b/setup/couchdb/initial_import/bedroom_init.dump @@ -11,6 +11,24 @@ "propertyId" : "nemaki:tag" }, "attachments" : { } +}, { + "document" : { + "_id" : "6174536bc714bfc3294b00306f000d5d", + "_rev" : "1-49dc721289fcc2baa2005a1dec576d98", + "admin" : true, + "created" : "2013-01-01T00:00:00.000+0000", + "creator" : "system", + "email" : "", + "lastName" : "solr", + "firstName" : "", + "modified" : "2013-01-01T00:00:00.000+0000", + "modifier" : "system", + "name" : "solr", + "passwordHash" : "$2a$10$YTaQCKmmf.f2XkcOPjVAVe1q3RR.Z2/YD6sotC/Kz.ZVlBYqhjIW6", + "type" : "user", + "userId" : "solr" + }, + "attachments" : { } }, { "document" : { "_id" : "83c150a42ffdcc49bb08041078b85b57", @@ -69,28 +87,10 @@ "userId" : "admin" }, "attachments" : { } -}, { - "document" : { - "_id" : "6174536bc714bfc3294b00306f000d5d", - "_rev" : "1-896182b5dcbb926e5209c3cbadb445fe", - "admin" : true, - "created" : "2013-01-01T00:00:00.000+0000", - "creator" : "system", - "email" : "", - "lastName" : "solr", - "firstName" : "", - "modified" : "2013-01-01T00:00:00.000+0000", - "modifier" : "system", - "name" : "solr", - "passwordHash": "$2a$10$YTaQCKmmf.f2XkcOPjVAVe1q3RR.Z2/YD6sotC/Kz.ZVlBYqhjIW6", - "type" : "user", - "userId" : "solr" - }, - "attachments" : { } }, { "document" : { "_id" : "94ee2cb22e260d582b5d66903f002175", - "_rev" : "1-28d8dffb424a3dc8c5558cfca16003a8", + "_rev" : "1-b060c4a5fbe02c8baf6b33bdfb7eb3fe", "created" : "2013-01-01T00:00:00.000+0000", "admin" : true, "creator" : "system", @@ -107,7 +107,7 @@ }, { "document" : { "_id" : "_design/_repo", - "_rev" : "1-cd9c679217df0f60f328b5ac93e23692", + "_rev" : "2-b150f447e433264ee7424bc238b676b2", "language" : "javascript", "views" : { "attachments" : { @@ -206,6 +206,9 @@ }, "changes" : { "map" : "function(doc) { if (doc.type == 'change') emit(doc._id, doc) }" + }, + "childrenNames" : { + "map" : "function(doc) {var result={}; result[doc.name]=doc._id; if (doc.type == 'cmis:document' || doc.type == 'cmis:folder') emit(doc.parentId, doc.name);}" } } }, From eaea6aed7e35aff1619e06068e909722777e1049 Mon Sep 17 00:00:00 2001 From: linzhixing Date: Fri, 8 Jan 2016 19:54:46 +0900 Subject: [PATCH 18/20] Ignore ui/lib folder --- ui/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/.gitignore b/ui/.gitignore index 767e7a5e..7b676787 100644 --- a/ui/.gitignore +++ b/ui/.gitignore @@ -17,3 +17,4 @@ conf/custom.properties *.log /bin/ /.cache-* +lib/* From 97f9352490206128a51fc6396f514e88304ecbba Mon Sep 17 00:00:00 2001 From: linzhixing Date: Fri, 8 Jan 2016 19:56:55 +0900 Subject: [PATCH 19/20] Add nemakiware-common-2.3.6.jar to core's lib folder --- .../WEB-INF/lib/nemakiware-common-2.3.6.jar | Bin 0 -> 3011 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 core/src/main/webapp/WEB-INF/lib/nemakiware-common-2.3.6.jar diff --git a/core/src/main/webapp/WEB-INF/lib/nemakiware-common-2.3.6.jar b/core/src/main/webapp/WEB-INF/lib/nemakiware-common-2.3.6.jar new file mode 100644 index 0000000000000000000000000000000000000000..0dcd7a352f85e74db6a979cca3677655934184f2 GIT binary patch literal 3011 zcmWIWW@h1H0D(k76%Q~2N^k;cU)K;vT~9wZ{Q#&k4u%AvvUn$5);yqeI}nQ?EAw^q z^K^3!4$<><`|Nw>w2!y0-bG$-U9EFx&TkGfxMKX^X_1cCxf43xx=tMIPnLvD5z{`P zQn7Q6mvOOI$y}|qB1NBzKYM?2RMDSa9GI2lnZ*@xXQP6lrE=&&^Nl*D{s$w@dz_b8 zr0sfLTU9z`V(UD|J(3s9;`A6`?qdME59lN~UfPP(fm9dS)6PWdg{` z@=|jXvorCi7RRDGIX^cyKM$@65|m2+0#;Z8-KfR}#JDxN78T_eIp?RO>LuqS78kcp zi7dWsAaFc<%Tl!|PA?DE-VZ-qyCp^`>{3HAyS!%Ys}&n>?Xn0vUKaIhV?|OMyB&jk zSEA_dl@&=wkAHl>{;z!Nr(65~|M|np(4VlAN%=#X%)P$D)=b7{O2c!HFK^s`Bxir* zVmo8bIa{{<;9Gyp=H`m3N-0(8ZkE2QDU+VsoV2!i$IX0i@sc;XS+lQ{-w|cjXw*~< zJe_(aCNX~2y!VnH9>(uH8YMp?+hMIw!`JVsYjQPCIxS}Gac~Xf&9yUL5La};jQ!4m zxpD=wtL|-jJc~_d>Q}D4CwgyZOe>ol>2uRwXokk?>vIpdJzjok#~Z7%#|ra9^S1cL z_Sb%qx!n-md#~xlUp2a7S#l}U zkIT+;>+&u%x!+^N6ux%tTP<vx6A8RxSz7H zjF}mpY{uySP_ps#fA8j4d7q`5x2f*3^y)m5X@6hDQ?9g9&xy&s%7(L2@3L)8j*TBH z|Mwf)HBN74&f~l)du&nd|9zXzExs{b%AI$m$-7tjm~qU}Qo3bx*5%`_pFzEna#ObnEir7|>9ip6hDU1s z?dfN2gg^c&_^wyh-rVp$^WOO@D|LCcx5|a*oYv9mOUt`|VY0PT{0uEIDW&C^<;J%J zU)}lEY}|8DZCR?&`->LSb}OwpJ*920Mx%BC$9`Rg@3)N^d}iDIeMf9G8L!SnB2Rt?|JJ;%f+=x5b%{@ipd ze8T#y8s49~j+sx$&#K}6x$Ri_g!frB{6F^{!Mjl1#=`}m#W9(?`aAk#R#Vy*_$15up^_Kim!ue{!mC@0X1JAPp1gBN$XiDjvX zoQhdCDq||nD$oNLA$pLqp**oD6`s{G4KO9n0EAh(7^O!^m6Au7vhRZcMh1qjObiS* zL&h|_jacB7M|@}AdoF_pZU_V1MBspYubyZEZ8Zh*F3*&L)y%cYlcS^=c;zjkGSoTZ<6kp^|gP;lWC7rT>aB7w%hov z^jF*}7Es%?(XPR*_W`Fl_qszbwpEI4$q{IFdN<+IUcODqY#ee&5>k$xlzn{e@M_h^ zyVh-0s#wDI`J>E62k#R94-CyuX3Iw?hB|tuaqK%3;l5GoML{M@W3I1j{+{^{6plsy zZ|40WmvA`1zeV5m{@OJxn|7JX$cbK8I#RpGK2>}E|LN*?x{hCGb8=wzYIt;g0r%I- z!jJcE^V)S%ZL!U*>o*PWCYbPMM=uhc<-biL^>nS_s{_AY{=2jN;AJai8R__YKI!nJ z#sRKbA03?M3#u|Jf!LXnm?|jBFGwva$xJPFJ$aC?$$*F9LiPSdoaxhZCHPe4^s3Bx z!mcG^bT%qT?b!b7v#)<&#my}(I`8AZgN=M*E7(NecwU%)@wi#bHTF08%5L&f7B{{v zx#SwYn=S0}^|HCUk3Z|UzQy99&-pKE$qL$;3s?U6wSKv0aabcTEi*ESFyn420R036 z0t{~*K{PxkA+%v{I)D^|z>-FFAPLuo)Q~`!fLV8gDt8C~S$rJG1XuM4mx5X=FeM-w zRM|rSNW%*t6RGOQtqoN9LjXt{KQPC^wZWSLxOIaX0|?!=SaicPH_Q<1jRTl5OB#!C z8-mtUKn^}^Wgg67|Np;dL5cua2?%o#W)TJ|0}+~KSTQtXFA;GY2r3g12F4O+Ahr?` zW(5ZWwlWfC$&$tm Date: Fri, 8 Jan 2016 19:57:35 +0900 Subject: [PATCH 20/20] version 2.3.7 --- setup/installer/install.xml | 2 +- ui/app/controllers/Application.java | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/setup/installer/install.xml b/setup/installer/install.xml index 6cccd281..52fec8f1 100755 --- a/setup/installer/install.xml +++ b/setup/installer/install.xml @@ -3,7 +3,7 @@ NemakiWare - 2.3.6 + 2.3.7 http://www.nemakiware.com/