From fe3fc5fff8fb51cce521dc172b7ff2a80bd1b660 Mon Sep 17 00:00:00 2001 From: Dave Ward Date: Thu, 25 Oct 2012 16:38:22 +0000 Subject: [PATCH] Merged V4.1-BUG-FIX to HEAD 42933: ALF-15328 could we add a sample log4j file in 'extension'? 42935: ALF-16455: Merged V3.4-BUG-FIX (3.4.12) to V4.1-BUG-FIX (4.1.2) 42934: ALF-16454 TransformerDebug id values have gaps 42955: ALF-15328 could we add a sample log4j file in 'extension'? - missing j in file name 42982: Merged DEV to V4.1-BUG-FIX 42873: ALF-16194: Checkout/Checkin leaves Lockable aspect on which disables autoVersionOnUpdateProps DoNothingCopyBehaviourCallback policy has been set for lockable aspect (implemented in LockServiceImpl); Unit test has been added. 43000: Merged BRANCHES/DEV/BELARUS/V4.1-BUG-FIX-2012_10_19 to BRANCHES/DEV/V4.1-BUG-FIX: 42936: ALF-11573: It's impossible to Modify settings for document versions 43010: ALF-16006 MT: Document Library is absent after upgrade from 3.4.x to 4.1.x (eg. 3.4.10 -> 4.1.1) - applied patch suggested in JIRA 43017: ALF-16457: "CmisObjectNotFoundException: No corresponding type found! Not a CMIS object?" thrown by AlfrescoCmisServiceImpl.getChildren - Check CMISNodeInfo for invalid type before processing. 43019: ALF-14353: Upgrade Activiti dependencies in Maven build 43022: ALF-14353: Upgrade Activiti dependencies in Maven build 43027: Merged DEV to V4.1-BUG-FIX 42426: ALF-15577: " does not support the method HEAD " when opening a MS Access file with "View In Browser" 43029: Merged DEV to 4.1-BUG-FIX (4.1.2) 42988: ALF-15791: Custom Types,Aspects defined with prefix using underscore cannot be loaded by API calls like api/classes/ Identical logic for old and new ClassDef API was moved to abstract super classes 42924: ALF-15791: Custom Types,Aspects defined with prefix using underscore cannot be loaded by API calls like api/classes/ New set of URL templates for class defenitions were provided to support requests with separated namespace prefixes and names 43031: ALF-16489: Typo in column-name of newly created index 43041: Merged DEV to 4.1-BUG-FIX (4.1.2) 43040: ALF-16425: API call to return all classes, returns wrong properties in classes Propertydefs and assocdefs are reordered to corelate with classdefs. Unit test was added for issue. 43052: ALF-16194: Checkout/Checkin leaves Lockable aspect on which disables autoVersionOnUpdateProps - Fix failing test 43055: Probable fix for ALF-15813. Replaced the 'skipCount' with the one in the query request, rather than query result. The Lucene query result does not support the reporting of the skipCount. 43065: Merged V3.4-BUG-FIX to V4.1-BUG-FIX 42958: ALF-14421: Inconsistencies when applying Versionable Aspect - We think the most preferable fix that will result in the best consistency between Share and old Explorer behaviour is to make the adding of the versionable aspect always result in an initial MAJOR version, if a version type has not been specified. Major/minor versions can still be controlled explicitly by checkout/checkin the versionable aspect properties and the version service API. 42998: ALF-14421: Fixed version label unit test fallout - back to what it used to be. 42999: Fix for ALF-16261 - IE script error occurs when email space users providing there are no users in this space 43006: Removed dependency on Apache Commons StringUtils. See ALF-12541, ALF-14254, AMZNSSS-17 43028: ALF-14722: Merged V4.1-BUG-FIX to V3.4-BUG-FIX 42902: Merged DEV to V4.1-BUG-FIX 42519: ALF-13588: Google Doc failed to authenticate after incorrect password being entered for google account Add ability to unregister class behaviours. Unregister googledocs behaviours when subsystem stops. 43066: ALF-16502: Merged PATCHES/V4.0.2 to V4.1-BUG-FIX 42969: Merged DEV to PATCHES/V4.0.2 42967: MNT-158: SharePoint Protocol Opening Documents in Read-Only for Site Consumer with Collaborator Privileges Remove manual throwing of AccessDeniedException is user has "consumer" or "contributor" role. Create "links" container from system user. 43067: Merged PATCHES/V4.1.1 to V4.1-BUG-FIX 42470: ALF-16503 / ALF-16256: Upgrade 3.4.6 HF to 4.1.1 - DuplicateChildNodeNameException: Duplicate child name not allowed: surf-config 42591: ALF-16504 / ALF-16332: Fixed synchronization around org.alfresco.repo.dictionary.NamespaceDAOImpl.namespaceRegistryCache - There was no 'double checking' after releasing the write lock, meaning that under high concurrency lots of threads would queue up to continuously re-initialize the registry. 42705: ALF-16504/ ALF-16332, ALF-16377: Revisited synchronization and initialization of mutually-dependent DictionaryDAO and NamespaceDAO to prevent deadlock and simultaneous re-initialization in more than one thread 43068: Merged DEV to V4.1-BUG-FIX - TODO: Update DB2 DDL in activiti 42388: ALF-15828: DB2: unexpected index found in database. Modify activity create script for db2 to create normal name for ACT_HI_PROCINST.PROC_INST_ID_ index. Introduce patch that will rename autogenerated name to normal name for ACT_HI_PROCINST.PROC_INST_ID_ index. Update schema reference file for DB2. 42429: ALF-15828: DB2: unexpected index found in database. Fix scripts from ALF-14983 and ALF-16038 to drop/recreate tables in DB2. 43069: ALF-11214: IMAP subsystem is not successfully restarted after incorrect modification of IMAP properties via Admin Console Stopped ChildApplicationContextFactory from caching a stale application context that didn't successfully refresh. 43071: ALF-13660: When using kerberos SSO, non domain explorer users requesting a download URL get a login page but after login do not get the requested document - Now the Web Client authentication filters use the same mechanism for preserving the request URL through a redirect to the login page 43076: ALF-15828: Fixed merge issue 43079: ALF-13602: Incorrect number of documents displayed in Share DocLib when a file is checked out - added ability for FileFolderService.list (-> FileFolder GetChildren CQ) to filter by one or more aspects, eg. cm:checkedOut 43080: ALF-14421: More version label unit test fallout 43092: Fix ALF-16460: Users may receive activity feed entries (from people they follow) for moderated sites to which they do not belong - also add unit test 43093: Fix for ALF-16091 - Unable to inline edit javascript file. 43096: Fix for ALF-16283 - When document is checked out, 'Edit Online' and 'Upload New Version' options should not be visible on the original document. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@43103 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/cmis/content.head.desc.xml | 33 + .../prefixed/assocdefinition.lib.ftl | 60 + .../prefixed/association.get.desc.xml | 8 + .../prefixed/association.get.json.ftl | 6 + .../prefixed/associations.get.desc.xml | 8 + .../prefixed/associations.get.json.ftl | 14 + .../dictionary/prefixed/class.get.desc.xml | 8 + .../dictionary/prefixed/class.get.json.ftl | 4 + .../dictionary/prefixed/classdetails.lib.ftl | 111 ++ .../dictionary/prefixed/classes.get.desc.xml | 8 + .../dictionary/prefixed/classes.get.json.ftl | 6 + .../prefixed/properties.get.desc.xml | 9 + .../prefixed/properties.get.json.ftl | 8 + .../dictionary/prefixed/property.get.desc.xml | 8 + .../dictionary/prefixed/property.get.json.ftl | 6 + .../prefixed/propertydefinition.lib.ftl | 46 + .../prefixed/subclasses.get.desc.xml | 8 + .../prefixed/subclasses.get.json.ftl | 7 + .../documentlibrary-v2/filters.lib.js | 3 +- .../web-scripts-application-context.xml | 18 + .../repo/web/scripts/content/ContentInfo.java | 100 ++ .../dictionary/AbstractAssociationGet.java | 67 ++ .../dictionary/AbstractAssociationsGet.java | 126 ++ .../scripts/dictionary/AbstractClassGet.java | 72 ++ .../dictionary/AbstractClassesGet.java | 184 +++ .../dictionary/AbstractPropertiesGet.java | 120 ++ .../dictionary/AbstractPropertyGet.java | 68 ++ .../dictionary/AbstractSubClassesGet.java | 159 +++ .../scripts/dictionary/AssociationGet.java | 53 +- .../scripts/dictionary/AssociationsGet.java | 102 +- .../repo/web/scripts/dictionary/ClassGet.java | 49 +- .../web/scripts/dictionary/ClassesGet.java | 168 +-- .../dictionary/DictionaryRestApiTest.java | 76 +- .../dictionary/DictionaryWebServiceBase.java | 102 ++ .../web/scripts/dictionary/PropertiesGet.java | 97 +- .../web/scripts/dictionary/PropertyGet.java | 54 +- .../web/scripts/dictionary/SubClassesGet.java | 142 +-- .../dictionary/prefixed/AssociationGet.java | 72 ++ .../dictionary/prefixed/AssociationsGet.java | 58 + .../scripts/dictionary/prefixed/ClassGet.java | 55 + .../dictionary/prefixed/ClassesGet.java | 50 + .../prefixed/DictionaryRestApiTest.java | 1022 +++++++++++++++++ .../dictionary/prefixed/PropertiesGet.java | 56 + .../dictionary/prefixed/PropertyGet.java | 75 ++ .../dictionary/prefixed/SubClassesGet.java | 81 ++ .../BaseKerberosAuthenticationFilter.java | 2 +- .../auth/BaseNTLMAuthenticationFilter.java | 4 +- .../auth/BaseSSOAuthenticationFilter.java | 5 +- 48 files changed, 3043 insertions(+), 555 deletions(-) create mode 100644 config/alfresco/templates/webscripts/org/alfresco/cmis/content.head.desc.xml create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/assocdefinition.lib.ftl create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/association.get.desc.xml create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/association.get.json.ftl create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/associations.get.desc.xml create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/associations.get.json.ftl create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/class.get.desc.xml create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/class.get.json.ftl create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classdetails.lib.ftl create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classes.get.desc.xml create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classes.get.json.ftl create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/properties.get.desc.xml create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/properties.get.json.ftl create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/property.get.desc.xml create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/property.get.json.ftl create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/propertydefinition.lib.ftl create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/subclasses.get.desc.xml create mode 100644 config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/subclasses.get.json.ftl create mode 100644 source/java/org/alfresco/repo/web/scripts/content/ContentInfo.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/AbstractAssociationGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/AbstractAssociationsGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/AbstractClassGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/AbstractClassesGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/AbstractPropertiesGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/AbstractPropertyGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/AbstractSubClassesGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/AssociationGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/AssociationsGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/ClassGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/ClassesGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/DictionaryRestApiTest.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/PropertiesGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/PropertyGet.java create mode 100644 source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/SubClassesGet.java diff --git a/config/alfresco/templates/webscripts/org/alfresco/cmis/content.head.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/cmis/content.head.desc.xml new file mode 100644 index 0000000000..6239aef9ac --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/cmis/content.head.desc.xml @@ -0,0 +1,33 @@ + + Head Content + Head method for the specified document. + + + + /api/node/content{property}/{store_type}/{store_id}/{id}?a={attach?}&streamId={streamId?} + + + + id + the node id of the object + + + property + the name of the content property to retrieve content from + cm:content + + + attach + if true, force download of content as attachment + false + + + streamId + if provided, download the rendition of the content as identified by the stream id + + + + argument + guest + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/assocdefinition.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/assocdefinition.lib.ftl new file mode 100644 index 0000000000..c2a1c2ae10 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/assocdefinition.lib.ftl @@ -0,0 +1,60 @@ +<#macro assocDefJSON assocdefs> +<#escape x as jsonUtils.encodeJSONString(x)> + { + <#if assocdefs.name?exists> + "name" : "${assocdefs.name.toPrefixString()}", + + <#if assocdefs.title?exists> + "title" : "${assocdefs.title}", + <#else> + "title" : "", + + <#if assocdefs.description?exists> + "description" : "${assocdefs.description}", + <#else> + "description" : "", + + <#if assocdefs.isChild() == true> + "isChildAssociation" : true, + <#else> + "isChildAssociation" : false, + + <#if assocdefs.isProtected() == true> + "protected" : true, + <#else> + "protected" : false, + + "source" : { + <#if assocdefs.getSourceClass().name?exists> + "class" : "${assocdefs.getSourceClass().name.toPrefixString()}", + + <#if assocdefs.getSourceRoleName()?exists> + "role" : "${assocdefs.getSourceRoleName().toPrefixString()}", + + "mandatory" : ${assocdefs.isSourceMandatory()?string}, + "many" : ${assocdefs.isSourceMany()?string} + }, + "target" : { + <#if assocdefs.getTargetClass().name?exists> + "class" : "${assocdefs.getTargetClass().name.toPrefixString()}", + + <#if assocdefs.getTargetRoleName()?exists> + "role" : "${assocdefs.getTargetRoleName().toPrefixString()}", + + "mandatory" : ${assocdefs.isTargetMandatory()?string}, + "many" : ${assocdefs.isTargetMany()?string} + }, + <#if assocdefs.isChild() == true> + <#if assocdefs.getRequiredChildName()?exists> + "requiredChildName" : "${assocdefs.getRequiredChildName()}", + + <#if assocdefs.getDuplicateChildNamesAllowed() == true> + "duplicateChildNameAllowed" : true, + <#else> + "duplicateChildNameAllowed" : false, + + + "url" : "${"/api/defclasses/" + url.templateArgs.prefix + "/" + url.templateArgs.shortClassName + "/association/" + assocdefs.name.toPrefixString()?replace(":","/")}" + } + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/association.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/association.get.desc.xml new file mode 100644 index 0000000000..3e341a390b --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/association.get.desc.xml @@ -0,0 +1,8 @@ + + Get association definitions + Get the collection of association definitions. + /api/defclasses/{prefix}/{shortClassName}/association/{assocprefix}/{assocname} + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/association.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/association.get.json.ftl new file mode 100644 index 0000000000..186f9fb182 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/association.get.json.ftl @@ -0,0 +1,6 @@ +<#import "assocdefinition.lib.ftl" as assocDefLib/> +<#if assocdefs?exists> +<@assocDefLib.assocDefJSON assocdefs=assocdefs/> +<#else> +{} + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/associations.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/associations.get.desc.xml new file mode 100644 index 0000000000..5c13f79875 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/associations.get.desc.xml @@ -0,0 +1,8 @@ + + Get association definitions for classname + Gets the collection of association definitions for a given classname. + /api/defclasses/{prefix}/{shortClassName}/associations?af={associationFilter?}&nsp={namespacePrefix?}&n={name?} + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/associations.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/associations.get.json.ftl new file mode 100644 index 0000000000..c188eb0ac8 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/associations.get.json.ftl @@ -0,0 +1,14 @@ +<#import "assocdefinition.lib.ftl" as assocDefLib/> +[ + <#list assocdefs as assocdefs> + <#if individualproperty?exists> + <#if assocdefs.name == individualproperty.name> + <@assocDefLib.assocDefJSON assocdefs=assocdefs/> + <#break> + + <#else> + <@assocDefLib.assocDefJSON assocdefs=assocdefs/> + <#if assocdefs_has_next>, + + +] \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/class.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/class.get.desc.xml new file mode 100644 index 0000000000..3b8cb2f55c --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/class.get.desc.xml @@ -0,0 +1,8 @@ + + Get class definitions for classname + Gets the collection of class definitions for a given classname. + /api/defclasses/{prefix}/{shortClassName} + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/class.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/class.get.json.ftl new file mode 100644 index 0000000000..9ce7d992a0 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/class.get.json.ftl @@ -0,0 +1,4 @@ +<#import "classdetails.lib.ftl" as classdetailsDefLib/> +<#list classdefs as classdef> +<@classdetailsDefLib.classDefJSON classdef=classdef key=classdef_index/><#if classdef_has_next>, + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classdetails.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classdetails.lib.ftl new file mode 100644 index 0000000000..3b078fc217 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classdetails.lib.ftl @@ -0,0 +1,111 @@ +<#macro classDefJSON classdef key> +<#local classdefprefix=classdef.name.toPrefixString()?replace(":","/")> +<#escape x as jsonUtils.encodeJSONString(x)> + { + <#if classdef.name??>"name": "${classdef.name.toPrefixString()}", + "isAspect": ${classdef.isAspect()?string}, + "isContainer": ${classdef.isContainer()?string}, + "title": "${classdef.title!""}", + "description": "${classdef.description!""}", + "parent": + { + <#if classdef.parentName??> + "name": "${classdef.parentName.toPrefixString()}", + "title": "${classdef.parentName.getLocalName()}", + "url": "/api/defclasses/${classdef.parentName.toPrefixString()?replace(":","/")}" + + }, + "defaultAspects": + { + <#if classdef.defaultAspects??> + <#list classdef.defaultAspects as aspectdef> + "${aspectdef.name.toPrefixString()}": + { + "name": "${aspectdef.name.toPrefixString()}", + "title": "${aspectdef.title!""}", + "url": "/api/defclasses/${classdefprefix}/property/${aspectdef.name.toPrefixString()?replace(":","/")}" + }<#if aspectdef_has_next>, + + + }, + "properties": + { + <#list propertydefs[key] as propertydef> + "${propertydef.name.toPrefixString()}": + { + "name": "${propertydef.name.toPrefixString()}", + "title": "${propertydef.title!""}", + "description": "${propertydef.description!""}", + "dataType": <#if propertydef.dataType??>"${propertydef.dataType.name.toPrefixString()}"<#else>"", + "defaultValue": <#if propertydef.defaultValue??>"${propertydef.defaultValue}"<#else>null, + "multiValued": ${propertydef.multiValued?string}, + "mandatory": ${propertydef.mandatory?string}, + "enforced": ${propertydef.mandatoryEnforced?string}, + "protected": ${propertydef.protected?string}, + "indexed": ${propertydef.indexed?string}, + "url": "/api/defclasses/${classdefprefix}/property/${propertydef.name.toPrefixString()?replace(":","/")}" + }<#if propertydef_has_next>, + + }, + "associations": + { + <#assign isfirst=true> + <#list assocdefs[key] as assocdef> + <#if !isfirst && !assocdef.isChild()>, + <#if !assocdef.isChild()> + <#assign isfirst=false> + "${assocdef.name.toPrefixString()}": + { + "name": "${assocdef.name.toPrefixString()}", + "title": "${assocdef.title!""}", + "url": "/api/defclasses/${classdefprefix}/association/${assocdef.name.toPrefixString()?replace(":","/")}", + "source": + { + <#if assocdef.getSourceClass().name??>"class": "${assocdef.getSourceClass().name.toPrefixString()}", + <#if assocdef.getSourceRoleName()??>"role": "${assocdef.getSourceRoleName().toPrefixString()}", + "mandatory": ${assocdef.isSourceMandatory()?string}, + "many": ${assocdef.isSourceMany()?string} + }, + "target": + { + <#if assocdef.getTargetClass().name??>"class": "${assocdef.getTargetClass().name.toPrefixString()}", + <#if assocdef.getTargetRoleName()??>"role": "${assocdef.getTargetRoleName().toPrefixString()}", + "mandatory": ${assocdef.isTargetMandatory()?string}, + "many": ${assocdef.isTargetMany()?string} + } + } + + + }, + "childassociations": + { + <#assign isfirst=true> + <#list assocdefs[key] as assocdef> + <#if !isfirst && assocdef.isChild()>, + <#if assocdef.isChild()> + <#assign isfirst=false> + "${assocdef.name.toPrefixString()}": + { + <#if assocdef.name??>"name": "${assocdef.name.toPrefixString()}", + "title": "${assocdef.title!""}", + "url": "/api/defclasses/${classdefprefix}/association/${assocdef.name.toPrefixString()?replace(":","/")}", + "source": + { + <#if assocdef.getSourceClass().name??>"class": "${assocdef.getSourceClass().name.toPrefixString()}", + "mandatory": ${assocdef.isSourceMandatory()?string}, + "many": ${assocdef.isSourceMany()?string} + }, + "target": + { + <#if assocdef.getTargetClass().name??>"class": "${assocdef.getTargetClass().name.toPrefixString()}", + "mandatory": ${assocdef.isTargetMandatory()?string}, + "many": ${assocdef.isTargetMany()?string} + } + } + + + }, + "url": "/api/defclasses/${classdefprefix}" + } + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classes.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classes.get.desc.xml new file mode 100644 index 0000000000..9e07980c50 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classes.get.desc.xml @@ -0,0 +1,8 @@ + + Get class definitions + Gets the collection of class definitions - parameters classfilter , namespaceprefix and name. + /api/defclasses?cf={classFilter?}&nsp={namespacePrefix?}&n={name?} + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classes.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classes.get.json.ftl new file mode 100644 index 0000000000..c502a9fe75 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/classes.get.json.ftl @@ -0,0 +1,6 @@ +<#import "classdetails.lib.ftl" as classdetailsDefLib/> +[ +<#list classdefs as classdef> +<@classdetailsDefLib.classDefJSON classdef=classdef key=classdef_index/><#if classdef_has_next>, + +] \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/properties.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/properties.get.desc.xml new file mode 100644 index 0000000000..4cebc10f72 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/properties.get.desc.xml @@ -0,0 +1,9 @@ + + Get property definitions + Gets the collection of property definitions. + /api/defclasses/{prefix}/{shortClassName}/properties?nsp={namespacePrefix?}&n={name?} + /api/defproperties?nsp={namespacePrefix?}&n={name?} + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/properties.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/properties.get.json.ftl new file mode 100644 index 0000000000..cec1d3023d --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/properties.get.json.ftl @@ -0,0 +1,8 @@ +<#import "propertydefinition.lib.ftl" as propertyDefLib/> +[ + <#list propertydefs as propertydefinitions> + <@propertyDefLib.propertyDefJSON propertydefs=propertydefinitions/> + <#if propertydefinitions_has_next>, + +] + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/property.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/property.get.desc.xml new file mode 100644 index 0000000000..890c4c2524 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/property.get.desc.xml @@ -0,0 +1,8 @@ + + Get property definitions for classname + Gets the collection of property definitions for a given classname and property name. + /api/defclasses/{prefix}/{shortClassName}/property/{proppref}/{propname} + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/property.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/property.get.json.ftl new file mode 100644 index 0000000000..6870ea1ed9 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/property.get.json.ftl @@ -0,0 +1,6 @@ +<#import "propertydefinition.lib.ftl" as propertyDefLib/> +<#if propertydefs?exists> + <@propertyDefLib.propertyDefJSON propertydefs=propertydefs/> +<#else> + {} + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/propertydefinition.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/propertydefinition.lib.ftl new file mode 100644 index 0000000000..c204682101 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/propertydefinition.lib.ftl @@ -0,0 +1,46 @@ +<#macro propertyDefJSON propertydefs> + <#escape x as jsonUtils.encodeJSONString(x)> + { + <#if propertydefs.name?exists> + "name" : "${propertydefs.name.toPrefixString()}", + + <#if propertydefs.title?exists> + "title" : "${propertydefs.title}", + + <#if propertydefs.description?exists> + "description" : "${propertydefs.description}", + + <#if propertydefs.defaultValues?exists> + "defaultValues" : "${propertydefs.defaultValues}", + <#else> + "defaultValues" : "", + + <#if propertydefs.dataType?exists> + "dataType" : "${propertydefs.dataType.name.toPrefixString()}", + + "multiValued" : ${propertydefs.multiValued?string}, + "mandatory" : ${propertydefs.mandatory?string}, + "enforced" : ${propertydefs.mandatoryEnforced?string}, + "protected" : ${propertydefs.protected?string}, + "indexed" : ${propertydefs.indexed?string}, + "indexedAtomically" : ${propertydefs.indexedAtomically?string}, + "constraints" : + [<#-- + <#if propertydefs.constraints?exists> + <#list propertydefs.constraints as constraintdefs> + { + <#assign keys = constraintdefs.getConstraint()?keys> + <#list keys as key> + <#if key == "expression"> + "${key}" : <#if constraintdefs.getConstraint()[key]?exists>"${constraintdefs.getConstraint()[key]}" <#else>"has no value" + + <#if key_has_next>, + + }<#if constraintdefs_has_next>, + + --> + ], + "url" : "${"/api/property/" + propertydefs.name.toPrefixString()?replace(":","/")}" + } + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/subclasses.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/subclasses.get.desc.xml new file mode 100644 index 0000000000..f95d9b8101 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/subclasses.get.desc.xml @@ -0,0 +1,8 @@ + + Get subclasses definitions + Get the collection of subclasses definitions - parameters r=> recursive, classfilter , namespaceprefix and name. + /api/defclasses/{prefix}/{shortClassName}/subclasses?r={recursive?}&nsp={namespacePrefix?}&n={name?} + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/subclasses.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/subclasses.get.json.ftl new file mode 100644 index 0000000000..a6717a80a6 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/dictionary/prefixed/subclasses.get.json.ftl @@ -0,0 +1,7 @@ +<#import "classdetails.lib.ftl" as classdetailsDefLib/> +[ +<#list classdefs as classdef> +<@classdetailsDefLib.classDefJSON classdef=classdef key=classdef_index/> +<#if classdef_has_next>, + +] \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/filters.lib.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/filters.lib.js index 7a452d4f60..5b63b98aa7 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/filters.lib.js +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/filters.lib.js @@ -20,7 +20,8 @@ var Filters = "fm:forums", "fm:forum", "fm:topic", - "fm:post" + "fm:post", + "cm:checkedOut" ], /** diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index 247fc007d9..aa6a3810b3 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -345,6 +345,15 @@ + + + + + + + + + @@ -816,6 +825,15 @@ + + + + + + + + + diff --git a/source/java/org/alfresco/repo/web/scripts/content/ContentInfo.java b/source/java/org/alfresco/repo/web/scripts/content/ContentInfo.java new file mode 100644 index 0000000000..71bc7ea30b --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/content/ContentInfo.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. This file is part of Alfresco Alfresco is free software: you can redistribute it and/or modify it under the terms of the GNU + * Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Alfresco is distributed in + * the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General + * Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.content; + +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; + +import org.alfresco.cmis.CMISObjectReference; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.cmis.reference.ReferenceFactory; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; +import org.springframework.extensions.webscripts.WebScriptResponse; + +/** + * Content Info Service Get info about content from the Repository. + * + * @author alex.malinovsky + */ +public class ContentInfo extends StreamContent +{ + + private ReferenceFactory referenceFactory; + + public void setReferenceFactory(ReferenceFactory referenceFactory) + { + this.referenceFactory = referenceFactory; + } + + @Override + public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException + { + // create empty map of args + Map args = new HashMap(0, 1.0f); + // create map of template vars + Map templateVars = req.getServiceMatch().getTemplateVars(); + // create object reference from url + CMISObjectReference reference = referenceFactory.createObjectReferenceFromUrl(args, templateVars); + NodeRef nodeRef = reference.getNodeRef(); + if (nodeRef == null) + { + throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find " + reference.toString()); + } + + // render content + QName propertyQName = ContentModel.PROP_CONTENT; + + // Stream the content + streamContent(req, res, nodeRef, propertyQName, false); + } + + @Override + protected void streamContentImpl(WebScriptRequest req, WebScriptResponse res, ContentReader reader, boolean attach, Date modified, String eTag, String attachFileName) + throws IOException + { + setAttachment(res, attach, attachFileName); + + // establish mimetype + String mimetype = reader.getMimetype(); + String extensionPath = req.getExtensionPath(); + if (mimetype == null || mimetype.length() == 0) + { + mimetype = MimetypeMap.MIMETYPE_BINARY; + int extIndex = extensionPath.lastIndexOf('.'); + if (extIndex != -1) + { + String ext = extensionPath.substring(extIndex + 1); + mimetype = mimetypeService.getMimetype(ext); + } + } + + // set mimetype for the content and the character encoding + length for the stream + res.setContentType(mimetype); + res.setContentEncoding(reader.getEncoding()); + res.setHeader("Content-Length", Long.toString(reader.getSize())); + + // set caching + Cache cache = new Cache(); + cache.setNeverCache(false); + cache.setMustRevalidate(true); + cache.setMaxAge(0L); + cache.setLastModified(modified); + cache.setETag(eTag); + res.setCache(cache); + } + +} diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractAssociationGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractAssociationGet.java new file mode 100644 index 0000000000..ec236f0501 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractAssociationGet.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary; + +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/* + * Webscript to get the Associationdefinition for a given classname and association-name + * @author Viachaslau Tsikhanovich + */ + +public abstract class AbstractAssociationGet extends DictionaryWebServiceBase +{ + private static final String MODEL_PROP_KEY_ASSOCIATION_DETAILS = "assocdefs"; + + /** + * @Override method from DeclarativeWebScript + */ + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + { + Map model = new HashMap(1); + QName classQname = getClassQname(req); + QName associationQname = getAssociationQname(req); + + if (this.dictionaryservice.getClass(classQname).getAssociations().get(associationQname) != null) + { + model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, this.dictionaryservice.getClass(classQname).getAssociations().get(associationQname)); + } + + return model; + } + + /** + * @param req - webscript request + * @return qualified name for association + */ + protected abstract QName getAssociationQname(WebScriptRequest req); + + /** + * @param req - webscript request + * @return qualified name for class + */ + protected abstract QName getClassQname(WebScriptRequest req); + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractAssociationsGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractAssociationsGet.java new file mode 100644 index 0000000000..673ab94b7a --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractAssociationsGet.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary; + +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.service.cmr.dictionary.AssociationDefinition; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Webscript to get the Associationdefinitions for a given classname + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public abstract class AbstractAssociationsGet extends DictionaryWebServiceBase +{ + private static final String MODEL_PROP_KEY_ASSOCIATION_DETAILS = "assocdefs"; + private static final String MODEL_PROP_KEY_INDIVIDUAL_PROPERTY_DEFS = "individualproperty"; + private static final String REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX = "nsp"; + private static final String REQ_URL_TEMPL_VAR_NAME = "n"; + private static final String REQ_URL_TEMPL_VAR_ASSOCIATION_FILTER = "af"; + + /** + * @Override method from DeclarativeWebScript + */ + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + { + String associationFilter = req.getParameter(REQ_URL_TEMPL_VAR_ASSOCIATION_FILTER); + String namespacePrefix = req.getParameter(REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX); + String name = req.getParameter(REQ_URL_TEMPL_VAR_NAME); + + Map model = new HashMap(); + Map assocdef = new HashMap(); + QName associationQname = null; + QName classQname = getClassQname(req); + + if(associationFilter == null) + { + associationFilter = "all"; + } + + //validate association filter + if(isValidAssociationFilter(associationFilter) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the associationFilter - " + associationFilter + " - parameter in the URL"); + } + + // validate for the presence of both name and namespaceprefix + if((name == null && namespacePrefix != null) || + (name != null && namespacePrefix == null)) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Missing either name or namespaceprefix parameter in the URL - both combination of name and namespaceprefix is needed"); + } + + // check for association filters + if(associationFilter.equals("child")) + { + model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, this.dictionaryservice.getClass(classQname).getChildAssociations().values()); + } + else if(associationFilter.equals("general")) + { + for(AssociationDefinition assocname:this.dictionaryservice.getClass(classQname).getAssociations().values()) + { + if(assocname.isChild() == false) + { + assocdef.put(assocname.getName(), assocname); + } + } + model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, assocdef.values()); + } + else if(associationFilter.equals("all")) + { + model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, this.dictionaryservice.getClass(classQname).getAssociations().values()); + } + + // if both namespaceprefix and name parameters are given then, the combination namespaceprefix_name is used as the index to create the qname + if(name != null && namespacePrefix != null) + { + // validate the class combination namespaceprefix_name + associationQname = getAssociationQname(namespacePrefix, name); + + if(this.dictionaryservice.getClass(classQname).getAssociations().get(associationQname)== null) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "not a Valid - namespaceprefix_name combination"); + } + + model.put(MODEL_PROP_KEY_INDIVIDUAL_PROPERTY_DEFS, this.dictionaryservice.getClass(classQname).getAssociations().get(associationQname)); + } + + return model; + } + + /** + * @param req - webscript request + * @return qualified name for class + */ + protected abstract QName getClassQname(WebScriptRequest req); + + /** + * @param req - webscript request + * @return qualified name for association + */ + protected abstract QName getAssociationQname(String namespacePrefix, String name); + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractClassGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractClassGet.java new file mode 100644 index 0000000000..71f8f3eeda --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractClassGet.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.service.cmr.dictionary.AssociationDefinition; +import org.alfresco.service.cmr.dictionary.ClassDefinition; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Webscript to get the Classdefinitions for a classname eg. =>cm_author + * + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public abstract class AbstractClassGet extends DictionaryWebServiceBase +{ + private static final String MODEL_PROP_KEY_CLASS_DETAILS = "classdefs"; + private static final String MODEL_PROP_KEY_PROPERTY_DETAILS = "propertydefs"; + private static final String MODEL_PROP_KEY_ASSOCIATION_DETAILS = "assocdefs"; + + /** + * @Override method from DeclarativeWebScript + */ + protected Map executeImpl(WebScriptRequest req, Status status) + { + Map model = new HashMap(3); + Map classdef = new HashMap(); + Map> propdef = new HashMap>(); + Map> assocdef = new HashMap>(); + + QName classQname = getClassQname(req); + classdef.put(classQname, this.dictionaryservice.getClass(classQname)); + propdef.put(classQname, this.dictionaryservice.getClass(classQname).getProperties().values()); + assocdef.put(classQname, this.dictionaryservice.getClass(classQname).getAssociations().values()); + + model.put(MODEL_PROP_KEY_CLASS_DETAILS, classdef.values()); + model.put(MODEL_PROP_KEY_PROPERTY_DETAILS, propdef.values()); + model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, assocdef.values()); + + return model; + } + + /** + * @param req - webscript request + * @return qualified name for class + */ + protected abstract QName getClassQname(WebScriptRequest req); + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractClassesGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractClassesGet.java new file mode 100644 index 0000000000..7371b1070c --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractClassesGet.java @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.service.cmr.dictionary.AssociationDefinition; +import org.alfresco.service.cmr.dictionary.ClassDefinition; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Webscript to get the Classdefinitions using classfilter , namespaceprefix and name + * + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public abstract class AbstractClassesGet extends DictionaryWebServiceBase +{ + private static final String MODEL_PROP_KEY_CLASS_DEFS = "classdefs"; + private static final String MODEL_PROP_KEY_PROPERTY_DETAILS = "propertydefs"; + private static final String MODEL_PROP_KEY_ASSOCIATION_DETAILS = "assocdefs"; + + private static final String CLASS_FILTER_OPTION_TYPE1 = "all"; + private static final String CLASS_FILTER_OPTION_TYPE2 = "aspect"; + private static final String CLASS_FILTER_OPTION_TYPE3 = "type"; + + private static final String REQ_URL_TEMPL_VAR_CLASS_FILTER = "cf"; + private static final String REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX = "nsp"; + private static final String REQ_URL_TEMPL_VAR_NAME = "n"; + + /** + * @Override method from DeclarativeWebScript + */ + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + { + String classFilter = getValidInput(req.getParameter(REQ_URL_TEMPL_VAR_CLASS_FILTER)); + String namespacePrefix = getValidInput(req.getParameter(REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX)); + String name = getValidInput(req.getParameter(REQ_URL_TEMPL_VAR_NAME)); + + Map classdef = new HashMap(); + Map> propdef = new HashMap>(); + Map> assocdef = new HashMap>(); + Map model = new HashMap(); + + List qnames = new ArrayList(); + QName classQname = null; + QName myModel = null; + + // if classfilter is not given, then it defaults to all + if (classFilter == null) + { + classFilter = "all"; + } + + // validate classfilter + if (isValidClassFilter(classFilter) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classfilter - " + classFilter + " provided in the URL"); + } + + // name alone has no meaning without namespaceprefix + if (namespacePrefix == null && name != null) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Missing namespaceprefix parameter in the URL - both combination of name and namespaceprefix is needed"); + } + + // validate the namespaceprefix and name parameters => if namespaceprefix is given, then name has to be validated along with it + if (namespacePrefix != null) + { + // validate name parameter if present along with the namespaceprefix + if (name != null) + { + classQname = getClassQname(namespacePrefix, name); + classdef.put(classQname, this.dictionaryservice.getClass(classQname)); + propdef.put(classQname, this.dictionaryservice.getClass(classQname).getProperties().values()); + assocdef.put(classQname, this.dictionaryservice.getClass(classQname).getAssociations().values()); + } + else + { + // if name is not given then the model is extracted from the namespaceprefix, there can be more than one model associated with one namespaceprefix + String namespaceUri = namespaceService.getNamespaceURI(namespacePrefix); + for (QName qnameObj : this.dictionaryservice.getAllModels()) + { + if (qnameObj.getNamespaceURI().equals(namespaceUri)) + { + name = qnameObj.getLocalName(); + myModel = getQNameForModel(namespacePrefix, name); + + // check the classfilter to pull out either all or type or aspects + if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE1)) + { + qnames.addAll(this.dictionaryservice.getAspects(myModel)); + qnames.addAll(this.dictionaryservice.getTypes(myModel)); + } + else if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE3)) + { + qnames.addAll(this.dictionaryservice.getTypes(myModel)); + } + else if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE2)) + { + qnames.addAll(this.dictionaryservice.getAspects(myModel)); + } + } + } + } + } + + // if namespacePrefix is null, then check the classfilter to pull out either all or type or aspects + if (myModel == null) + { + if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE1)) + { + qnames.addAll(this.dictionaryservice.getAllAspects()); + qnames.addAll(this.dictionaryservice.getAllTypes()); + } + else if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE3)) + { + qnames.addAll(this.dictionaryservice.getAllTypes()); + } + else if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE2)) + { + qnames.addAll(this.dictionaryservice.getAllAspects()); + } + } + + if (classdef.isEmpty() == true) + { + for (QName qnameObj : qnames) + { + classdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj)); + propdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj).getProperties().values()); + assocdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj).getAssociations().values()); + } + } + + List classDefinitions = new ArrayList(classdef.values()); + Collections.sort(classDefinitions, new DictionaryComparators.ClassDefinitionComparator()); + model.put(MODEL_PROP_KEY_CLASS_DEFS, classDefinitions); + model.put(MODEL_PROP_KEY_PROPERTY_DETAILS, reorderedValues(classDefinitions, propdef)); + model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, reorderedValues(classDefinitions, assocdef)); + + return model; + } + + /** + * @param namespacePrefix - namespace prefix of the class + * @param name - local name of the class + * @return qualified name for model + */ + protected abstract QName getQNameForModel(String namespacePrefix, String name); + + /** + * @param req - webscript request + * @return qualified name for class + */ + protected abstract QName getClassQname(String namespacePrefix, String name); + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractPropertiesGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractPropertiesGet.java new file mode 100644 index 0000000000..6275f5b159 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractPropertiesGet.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.service.cmr.dictionary.PropertyDefinition; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Webscript to get the Propertydefinitions for a given classname eg. =>cm_person + * + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public abstract class AbstractPropertiesGet extends DictionaryWebServiceBase +{ + private static final String MODEL_PROP_KEY_PROPERTY_DETAILS = "propertydefs"; + private static final String PARAM_NAME = "name"; + private static final String REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX = "nsp"; + + /** + * @Override method from DeclarativeWebScript + */ + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + { + QName classQName = getClassQName(req); + + String[] names = req.getParameterValues(PARAM_NAME); + + String namespacePrefix = req.getParameter(REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX); + String namespaceURI = null; + if (namespacePrefix != null) + { + namespaceURI = this.namespaceService.getNamespaceURI(namespacePrefix); + } + + Map propMap = null; + if (classQName == null) + { + if (names != null) + { + propMap = new HashMap(names.length); + for (String name : names) + { + QName propQName = QName.createQName(name, namespaceService); + PropertyDefinition propDef = dictionaryservice.getProperty(propQName); + if (propDef != null) + { + propMap.put(propQName, propDef); + } + } + } + else + { + Collection propQNames = dictionaryservice.getAllProperties(null); + propMap = new HashMap(propQNames.size()); + for (QName propQName : propQNames) + { + propMap.put(propQName, dictionaryservice.getProperty(propQName)); + } + } + + } + else + { + // Get all the property definitions for the class + propMap = dictionaryservice.getClass(classQName).getProperties(); + } + + // Filter the properties by URI + List props = new ArrayList(propMap.size()); + for (Map.Entry entry : propMap.entrySet()) + { + if ((namespaceURI != null && namespaceURI.equals(entry.getKey().getNamespaceURI()) == true) || namespaceURI == null) + { + props.add(entry.getValue()); + } + } + + // Order property definitions by title + Collections.sort(props, new DictionaryComparators.PropertyDefinitionComparator()); + + // Pass list of property definitions to template + Map model = new HashMap(); + model.put(MODEL_PROP_KEY_PROPERTY_DETAILS, props); + return model; + } + + /** + * @param req - webscript request + * @return qualified name for class + */ + protected abstract QName getClassQName(WebScriptRequest req); + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractPropertyGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractPropertyGet.java new file mode 100644 index 0000000000..ff53bbf809 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractPropertyGet.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary; + +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Webscript to get the Propertydefinition for a given classname and propname + * + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public abstract class AbstractPropertyGet extends DictionaryWebServiceBase +{ + private static final String MODEL_PROP_KEY_PROPERTY_DETAILS = "propertydefs"; + + /** + * @Override method from DeclarativeWebScript + */ + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + { + Map model = new HashMap(1); + QName classQname = getClassQname(req); + QName propertyQname = getPropertyQname(req); + + if (this.dictionaryservice.getClass(classQname).getProperties().get(propertyQname) != null) + { + model.put(MODEL_PROP_KEY_PROPERTY_DETAILS, this.dictionaryservice.getClass(classQname).getProperties().get(propertyQname)); + } + + return model; + } + + /** + * @param req - webscript request + * @return qualified name for property + */ + protected abstract QName getPropertyQname(WebScriptRequest req); + + /** + * @param req - webscript request + * @return qualified name for class + */ + protected abstract QName getClassQname(WebScriptRequest req); + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractSubClassesGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractSubClassesGet.java new file mode 100644 index 0000000000..257c2a0836 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/AbstractSubClassesGet.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.service.cmr.dictionary.AssociationDefinition; +import org.alfresco.service.cmr.dictionary.ClassDefinition; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Webscript to get the Sub-Classdefinitions using classfilter , namespacePrefix and name + * + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public abstract class AbstractSubClassesGet extends DictionaryWebServiceBase +{ + private static final String MODEL_PROP_KEY_CLASS_DEFS = "classdefs"; + private static final String MODEL_PROP_KEY_PROPERTY_DETAILS = "propertydefs"; + private static final String MODEL_PROP_KEY_ASSOCIATION_DETAILS = "assocdefs"; + + private static final String REQ_URL_TEMPL_IMMEDIATE_SUB_TYPE_CHILDREN = "r"; + // private static final String REQ_URL_TEMPL_VAR_CLASS_FILTER = "cf"; + private static final String REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX = "nsp"; + private static final String REQ_URL_TEMPL_VAR_NAME = "n"; + + /** + * @Override method from DeclarativeWebScript + */ + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + { + String name = req.getParameter(REQ_URL_TEMPL_VAR_NAME); + String namespacePrefix = req.getParameter(REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX); + String recursiveValue = getValidInput(req.getParameter(REQ_URL_TEMPL_IMMEDIATE_SUB_TYPE_CHILDREN)); + + boolean recursive = true; + + Map classdef = new HashMap(); + Map> propdef = new HashMap>(); + Map> assocdef = new HashMap>(); + Map model = new HashMap(); + + String namespaceUri = null; + Collection qname = null; + boolean ignoreCheck = false; + + // validate recursive parameter => can be either true or false or null + if (recursiveValue == null) + { + recursive = true; + } + else if (recursiveValue.equalsIgnoreCase("true")) + { + recursive = true; + } + else if (recursiveValue.equalsIgnoreCase("false")) + { + recursive = false; + } + else + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the value for the parameter recursive=> " + recursiveValue + " can only be either true or false"); + } + + qname = getQNameCollection(req, recursive); + + // validate the name parameter + if (name != null) + { + if (isValidModelName(name) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the name parameter - " + name + " in the URL"); + } + } + + // validate the name parameter + if (namespacePrefix == null && name != null) + { + namespaceUri = namespaceService.getNamespaceURI(getPrefixFromModelName(name)); + } + + if (namespacePrefix != null && name == null) + { + namespaceUri = namespaceService.getNamespaceURI(namespacePrefix); + } + + if (namespacePrefix == null && name == null) + { + namespaceUri = null; + ignoreCheck = true; + } + + if (namespacePrefix != null && name != null) + { + validateClassname(namespacePrefix, name); + namespaceUri = namespaceService.getNamespaceURI(namespacePrefix); + } + + for (QName qnameObj : qname) + { + if ((ignoreCheck == true) || (qnameObj.getNamespaceURI().equals(namespaceUri))) + { + classdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj)); + propdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj).getProperties().values()); + assocdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj).getAssociations().values()); + } + } + + List classDefinitions = new ArrayList(classdef.values()); + Collections.sort(classDefinitions, new DictionaryComparators.ClassDefinitionComparator()); + model.put(MODEL_PROP_KEY_CLASS_DEFS, classDefinitions); + model.put(MODEL_PROP_KEY_PROPERTY_DETAILS, reorderedValues(classDefinitions, propdef)); + model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, reorderedValues(classDefinitions, assocdef)); + return model; + + } + + /** + * @param req - webscript request + * @param recursive - flag to get SubAspects or SubTypes recursively + * @return collection of qualified names for subclasses + */ + protected abstract Collection getQNameCollection(WebScriptRequest req, boolean recursive); + + /** + * Throws WebScriptException if classname is invalid + * @param namespacePrefix - namespace prefix of a class + * @param name - localname of a class + */ + protected abstract void validateClassname(String namespacePrefix, String name); + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/AssociationGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/AssociationGet.java index 2410aadcd2..a10a344de3 100644 --- a/source/java/org/alfresco/repo/web/scripts/dictionary/AssociationGet.java +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/AssociationGet.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2012 Alfresco Software Limited. * * This file is part of Alfresco * @@ -18,58 +18,45 @@ */ package org.alfresco.repo.web.scripts.dictionary; -import java.util.HashMap; -import java.util.Map; - import org.alfresco.service.namespace.QName; -import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptRequest; /* * Webscript to get the Associationdefinition for a given classname and association-name - * @author Saravanan Sellathurai + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich */ -public class AssociationGet extends DictionaryWebServiceBase +public class AssociationGet extends AbstractAssociationGet { - private static final String MODEL_PROP_KEY_ASSOCIATION_DETAILS = "assocdefs"; - private static final String DICTIONARY_CLASS_NAME = "classname"; - private static final String DICTIONARY_ASSOCIATION_NAME = "assocname"; + private static final String DICTIONARY_CLASS_NAME = "classname"; + private static final String DICTIONARY_ASSOCIATION_NAME = "assocname"; - /** - * @Override method from DeclarativeWebScript - */ - protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + @Override + protected QName getAssociationQname(WebScriptRequest req) { - String className = req.getServiceMatch().getTemplateVars().get(DICTIONARY_CLASS_NAME); String associationName = req.getServiceMatch().getTemplateVars().get(DICTIONARY_ASSOCIATION_NAME); - Map model = new HashMap(1); - QName classQname = null; - QName associationQname = null; - - //validate the classname - if(isValidClassname(className) == false) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + className + " - parameter in the URL"); - } - - classQname = QName.createQName(getFullNamespaceURI(className)); - if(associationName == null) { throw new WebScriptException(Status.STATUS_NOT_FOUND, "Missing parameter association name in the URL"); } - associationQname = QName.createQName(getFullNamespaceURI(associationName)); + return QName.createQName(getFullNamespaceURI(associationName)); + } + + @Override + protected QName getClassQname(WebScriptRequest req) + { + String className = req.getServiceMatch().getTemplateVars().get(DICTIONARY_CLASS_NAME); - if(this.dictionaryservice.getClass(classQname).getAssociations().get(associationQname) != null) - { - model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, this.dictionaryservice.getClass(classQname).getAssociations().get(associationQname)); - } + // validate the classname + if (isValidClassname(className) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + className + " - parameter in the URL"); + } - return model; + return QName.createQName(getFullNamespaceURI(className)); } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/AssociationsGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/AssociationsGet.java index 4880f35557..b51867801b 100644 --- a/source/java/org/alfresco/repo/web/scripts/dictionary/AssociationsGet.java +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/AssociationsGet.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2012 Alfresco Software Limited. * * This file is part of Alfresco * @@ -18,110 +18,36 @@ */ package org.alfresco.repo.web.scripts.dictionary; -import java.util.HashMap; -import java.util.Map; - -import org.alfresco.service.cmr.dictionary.AssociationDefinition; import org.alfresco.service.namespace.QName; -import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptRequest; /** * Webscript to get the Associationdefinitions for a given classname - * @author Saravanan Sellathurai + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich */ -public class AssociationsGet extends DictionaryWebServiceBase +public class AssociationsGet extends AbstractAssociationsGet { - private static final String MODEL_PROP_KEY_ASSOCIATION_DETAILS = "assocdefs"; - private static final String MODEL_PROP_KEY_INDIVIDUAL_PROPERTY_DEFS = "individualproperty"; - private static final String DICTIONARY_CLASS_NAME = "classname"; - private static final String REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX = "nsp"; - private static final String REQ_URL_TEMPL_VAR_NAME = "n"; - private static final String REQ_URL_TEMPL_VAR_ASSOCIATION_FILTER = "af"; + private static final String DICTIONARY_CLASS_NAME = "classname"; - /** - * @Override method from DeclarativeWebScript - */ - protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + @Override + protected QName getClassQname(WebScriptRequest req) { String className = req.getServiceMatch().getTemplateVars().get(DICTIONARY_CLASS_NAME); - String associationFilter = req.getParameter(REQ_URL_TEMPL_VAR_ASSOCIATION_FILTER); - String namespacePrefix = req.getParameter(REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX); - String name = req.getParameter(REQ_URL_TEMPL_VAR_NAME); - - Map model = new HashMap(); - Map assocdef = new HashMap(); - QName associationQname = null; - QName classQname = null; - - if(associationFilter == null) - { - associationFilter = "all"; - } - - //validate association filter - if(isValidAssociationFilter(associationFilter) == false) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the associationFilter - " + associationFilter + " - parameter in the URL"); - } - //validate classname - if(isValidClassname(className) == true) + if (isValidClassname(className) == false) { - classQname = QName.createQName(getFullNamespaceURI(className)); - } - else - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + className + " - parameter in the URL"); - } - - // validate for the presence of both name and namespaceprefix - if((name == null && namespacePrefix != null) || - (name != null && namespacePrefix == null)) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Missing either name or namespaceprefix parameter in the URL - both combination of name and namespaceprefix is needed"); - } - - // check for association filters - if(associationFilter.equals("child")) - { - model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, this.dictionaryservice.getClass(classQname).getChildAssociations().values()); - } - else if(associationFilter.equals("general")) - { - for(AssociationDefinition assocname:this.dictionaryservice.getClass(classQname).getAssociations().values()) - { - if(assocname.isChild() == false) - { - assocdef.put(assocname.getName(), assocname); - } - } - model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, assocdef.values()); - } - else if(associationFilter.equals("all")) - { - model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, this.dictionaryservice.getClass(classQname).getAssociations().values()); + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + className + " - parameter in the URL"); } + return QName.createQName(getFullNamespaceURI(className)); + } - // if both namespaceprefix and name parameters are given then, the combination namespaceprefix_name is used as the index to create the qname - if(name != null && namespacePrefix != null) - { - // validate the class combination namespaceprefix_name - associationQname = QName.createQName(getFullNamespaceURI(namespacePrefix + "_" + name)); - - if(this.dictionaryservice.getClass(classQname).getAssociations().get(associationQname)== null) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "not a Valid - namespaceprefix_name combination"); - } - - model.put(MODEL_PROP_KEY_INDIVIDUAL_PROPERTY_DEFS, this.dictionaryservice.getClass(classQname).getAssociations().get(associationQname)); - } - - return model; - + @Override + protected QName getAssociationQname(String namespacePrefix, String name) + { + return QName.createQName(getFullNamespaceURI(namespacePrefix + "_" + name)); } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/ClassGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/ClassGet.java index 12fcfef49c..54f4dec630 100644 --- a/source/java/org/alfresco/repo/web/scripts/dictionary/ClassGet.java +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/ClassGet.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2012 Alfresco Software Limited. * * This file is part of Alfresco * @@ -18,13 +18,6 @@ */ package org.alfresco.repo.web.scripts.dictionary; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.alfresco.service.cmr.dictionary.AssociationDefinition; -import org.alfresco.service.cmr.dictionary.ClassDefinition; -import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.namespace.QName; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; @@ -32,48 +25,26 @@ import org.springframework.extensions.webscripts.WebScriptRequest; /** * Webscript to get the Classdefinitions for a classname eg. =>cm_author - * @author Saravanan Sellathurai + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich */ -public class ClassGet extends DictionaryWebServiceBase +public class ClassGet extends AbstractClassGet { - private static final String MODEL_PROP_KEY_CLASS_DETAILS = "classdefs"; - private static final String MODEL_PROP_KEY_PROPERTY_DETAILS = "propertydefs"; - private static final String MODEL_PROP_KEY_ASSOCIATION_DETAILS = "assocdefs"; - private static final String DICTIONARY_CLASS_NAME = "className"; + private static final String DICTIONARY_CLASS_NAME = "className"; /** - * @Override method from DeclarativeWebScript + * @Override method from AbstractClassGet */ - protected Map executeImpl(WebScriptRequest req, Status status) + @Override + protected QName getClassQname(WebScriptRequest req) { String className = req.getServiceMatch().getTemplateVars().get(DICTIONARY_CLASS_NAME); - - Map model = new HashMap(3); - QName classQname = null; - Map classdef = new HashMap(); - Map> propdef = new HashMap>(); - Map> assocdef = new HashMap>(); - //validate the classname and throw appropriate error message - if(isValidClassname(className) == true) + if (isValidClassname(className) == false) { - classQname = QName.createQName(getFullNamespaceURI(className)); - classdef.put(classQname, this.dictionaryservice.getClass(classQname)); - propdef.put(classQname, this.dictionaryservice.getClass(classQname).getProperties().values()); - assocdef.put(classQname, this.dictionaryservice.getClass(classQname).getAssociations().values()); + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + className + " - parameter in the URL"); } - else - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + className + " - parameter in the URL"); - } - - model.put(MODEL_PROP_KEY_CLASS_DETAILS, classdef.values()); - model.put(MODEL_PROP_KEY_PROPERTY_DETAILS, propdef.values()); - model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, assocdef.values()); - - return model; - + return QName.createQName(getFullNamespaceURI(className)); } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/ClassesGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/ClassesGet.java index ad0212a981..405de1aabb 100644 --- a/source/java/org/alfresco/repo/web/scripts/dictionary/ClassesGet.java +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/ClassesGet.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2012 Alfresco Software Limited. * * This file is part of Alfresco * @@ -18,159 +18,33 @@ */ package org.alfresco.repo.web.scripts.dictionary; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.alfresco.service.cmr.dictionary.AssociationDefinition; -import org.alfresco.service.cmr.dictionary.ClassDefinition; -import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.namespace.QName; -import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; -import org.springframework.extensions.webscripts.WebScriptRequest; /** * Webscript to get the Classdefinitions using classfilter , namespaceprefix and name - * @author Saravanan Sellathurai + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich */ - -public class ClassesGet extends DictionaryWebServiceBase + +public class ClassesGet extends AbstractClassesGet { - private static final String MODEL_PROP_KEY_CLASS_DEFS = "classdefs"; - private static final String MODEL_PROP_KEY_PROPERTY_DETAILS = "propertydefs"; - private static final String MODEL_PROP_KEY_ASSOCIATION_DETAILS = "assocdefs"; - - private static final String CLASS_FILTER_OPTION_TYPE1 = "all"; - private static final String CLASS_FILTER_OPTION_TYPE2 = "aspect"; - private static final String CLASS_FILTER_OPTION_TYPE3 = "type"; - - private static final String REQ_URL_TEMPL_VAR_CLASS_FILTER = "cf"; - private static final String REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX = "nsp"; - private static final String REQ_URL_TEMPL_VAR_NAME = "n"; - - /** - * @Override method from DeclarativeWebScript - */ - protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + + @Override + protected QName getQNameForModel(String namespacePrefix, String name) { - String classFilter = getValidInput(req.getParameter(REQ_URL_TEMPL_VAR_CLASS_FILTER)); - String namespacePrefix = getValidInput(req.getParameter(REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX)); - String name = getValidInput(req.getParameter(REQ_URL_TEMPL_VAR_NAME)); - String className = null; - - Map classdef = new HashMap(); - Map> propdef = new HashMap>(); - Map> assocdef = new HashMap>(); - Map model = new HashMap(); - - List qnames = new ArrayList(); - QName classQname = null; - QName myModel = null; - - //if classfilter is not given, then it defaults to all - if(classFilter == null) - { - classFilter = "all"; - } - - //validate classfilter - if(isValidClassFilter(classFilter) == false) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classfilter - " + classFilter + " provided in the URL"); - } - - //name alone has no meaning without namespaceprefix - if(namespacePrefix == null && name != null) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Missing namespaceprefix parameter in the URL - both combination of name and namespaceprefix is needed"); - } - - //validate the namespaceprefix and name parameters => if namespaceprefix is given, then name has to be validated along with it - if(namespacePrefix != null) - { - //validate name parameter if present along with the namespaceprefix - if(name != null) - { - className = namespacePrefix + "_" + name; - if(isValidClassname(className) == false) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the name - " + name + "parameter in the URL"); - } - classQname = QName.createQName(getFullNamespaceURI(className)); - classdef.put(classQname, this.dictionaryservice.getClass(classQname)); - propdef.put(classQname, this.dictionaryservice.getClass(classQname).getProperties().values()); - assocdef.put(classQname, this.dictionaryservice.getClass(classQname).getAssociations().values()); - } - else - { - //if name is not given then the model is extracted from the namespaceprefix, there can be more than one model associated with one namespaceprefix - String namespaceUri = namespaceService.getNamespaceURI(namespacePrefix); - for(QName qnameObj:this.dictionaryservice.getAllModels()) - { - if(qnameObj.getNamespaceURI().equals(namespaceUri)) - { - name = qnameObj.getLocalName(); - myModel = QName.createQName(getFullNamespaceURI(namespacePrefix + "_" + name)); - - // check the classfilter to pull out either all or type or aspects - if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE1)) - { - qnames.addAll(this.dictionaryservice.getAspects(myModel)); - qnames.addAll(this.dictionaryservice.getTypes(myModel)); - } - else if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE3)) - { - qnames.addAll(this.dictionaryservice.getTypes(myModel)); - } - else if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE2)) - { - qnames.addAll(this.dictionaryservice.getAspects(myModel)); - } - } - } - } - } - - // if namespacePrefix is null, then check the classfilter to pull out either all or type or aspects - if(myModel == null) - { - if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE1)) - { - qnames.addAll(this.dictionaryservice.getAllAspects()); - qnames.addAll(this.dictionaryservice.getAllTypes()); - } - else if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE3)) - { - qnames.addAll(this.dictionaryservice.getAllTypes()); - } - else if (classFilter.equalsIgnoreCase(CLASS_FILTER_OPTION_TYPE2)) - { - qnames.addAll(this.dictionaryservice.getAllAspects()); - } - } - - if(classdef.isEmpty() == true) - { - for(QName qnameObj: qnames) - { - classdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj)); - propdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj).getProperties().values()); - assocdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj).getAssociations().values()); - } - } - - List classDefinitions = new ArrayList(classdef.values()); - Collections.sort(classDefinitions, new DictionaryComparators.ClassDefinitionComparator()); - model.put(MODEL_PROP_KEY_CLASS_DEFS, classDefinitions); - model.put(MODEL_PROP_KEY_PROPERTY_DETAILS, propdef.values()); - model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, assocdef.values()); - - return model; + return QName.createQName(getFullNamespaceURI(namespacePrefix + "_" + name)); } - - } \ No newline at end of file + + @Override + protected QName getClassQname(String namespacePrefix, String name) + { + String className = namespacePrefix + "_" + name; + if(isValidClassname(className) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the name - " + name + "parameter in the URL"); + } + return QName.createQName(getFullNamespaceURI(className)); + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/DictionaryRestApiTest.java b/source/java/org/alfresco/repo/web/scripts/dictionary/DictionaryRestApiTest.java index 5c86d5bf58..318919cb0f 100644 --- a/source/java/org/alfresco/repo/web/scripts/dictionary/DictionaryRestApiTest.java +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/DictionaryRestApiTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2012 Alfresco Software Limited. * * This file is part of Alfresco * @@ -21,7 +21,10 @@ package org.alfresco.repo.web.scripts.dictionary; import org.alfresco.repo.web.scripts.BaseWebScriptTest; import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest; import org.springframework.extensions.webscripts.TestWebScriptServer.Response; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.json.JSONObject; @@ -175,6 +178,66 @@ public class DictionaryRestApiTest extends BaseWebScriptTest //assertEquals(2, result.getJSONObject("associations").length()); } + private void validatePropertiesConformity(JSONArray classDefs) throws Exception + { + final int itemsToTest = 10; + for (int i = 0; (i < itemsToTest) && (i < classDefs.length()); ++i) + { + JSONObject classDef1 = classDefs.getJSONObject(i); + JSONArray propertyNames1 = classDef1.getJSONObject("properties").names(); + // properties of class obtained by api/classes + List propertyValues1 = Collections.emptyList(); + if (propertyNames1 != null) + { + propertyValues1 = new ArrayList(propertyNames1.length()); + for (int j = 0; j < propertyNames1.length(); j++) + { + propertyValues1.add(propertyNames1.getString(j)); + } + } + + String classUrl = classDef1.getString("url"); + assertTrue(classUrl.contains(URL_SITES)); + Response responseFromGetClassDef = sendRequest(new GetRequest(classUrl), 200); + JSONObject classDef2 = new JSONObject(responseFromGetClassDef.getContentAsString()); + assertTrue(classDef2.length() > 0); + assertEquals(200, responseFromGetClassDef.getStatus()); + assertEquals(classDef1.getString("name"), classDef2.getString("name")); + JSONArray propertyNames2 = classDef2.getJSONObject("properties").names(); + // properties of class obtained by api/classes/class + List propertyValues2 = Collections.emptyList(); + if (propertyNames2 != null) + { + propertyValues2 = new ArrayList(propertyNames2.length()); + for (int j = 0; j < propertyNames2.length(); j++) + { + propertyValues2.add(propertyNames2.getString(j)); + } + } + + Response responseFromGetPropertiesDef = sendRequest(new GetRequest(classUrl + "/properties"), 200); + JSONArray propertiesDefs = new JSONArray(responseFromGetPropertiesDef.getContentAsString()); + assertEquals(200, responseFromGetClassDef.getStatus()); + // properties of class obtained by api/classes/class/properties + List propertyValues3 = new ArrayList(propertiesDefs.length()); + for (int j = 0; j < propertiesDefs.length(); j++) + { + propertyValues3.add(propertiesDefs.getJSONObject(j).getString("name")); + } + + assertEquivalenceProperties(propertyValues1, propertyValues2); + assertEquivalenceProperties(propertyValues2, propertyValues3); + } + } + + private void assertEquivalenceProperties(List propertyValues1, List propertyValues2) + { + if ((propertyValues1.size() != propertyValues2.size()) || !propertyValues1.containsAll(propertyValues2)) + { + fail("Wrong properties in classes"); + } + } + public void testGetPropertyDef() throws Exception { Response response = sendRequest(new GetRequest("/api/classes/cm_auditable/property/cm_created"), 200); @@ -948,4 +1011,15 @@ public class DictionaryRestApiTest extends BaseWebScriptTest } + public void testGetClasses() throws Exception + { + GetRequest req = new GetRequest(URL_SITES); + Response response = sendRequest(req, 200); + JSONArray result = new JSONArray(response.getContentAsString()); + + assertTrue(result.length() > 0); + assertEquals(200, response.getStatus()); + validatePropertiesConformity(result); + } + } diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/DictionaryWebServiceBase.java b/source/java/org/alfresco/repo/web/scripts/dictionary/DictionaryWebServiceBase.java index 9a98e34125..e842443fe6 100644 --- a/source/java/org/alfresco/repo/web/scripts/dictionary/DictionaryWebServiceBase.java +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/DictionaryWebServiceBase.java @@ -18,8 +18,12 @@ */ package org.alfresco.repo.web.scripts.dictionary; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; +import java.util.Map; +import org.alfresco.service.cmr.dictionary.ClassDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.namespace.InvalidQNameException; import org.alfresco.service.namespace.NamespaceService; @@ -95,6 +99,26 @@ public abstract class DictionaryWebServiceBase extends DeclarativeWebScript return result; } + /** + * @param prefix - prefix for class name + * @param shortName - short class name + * @return qualified name for class name + */ + protected QName createClassQName(String prefix, String shortName) + { + QName result = null; + String url = namespaceService.getNamespaceURI(prefix); + if (url != null && url.length() != 0 && shortName != null && shortName.length() != 0) + { + QName classQName = QName.createQName(url, shortName); + if (dictionaryservice.getClass(classQName) != null) + { + result = classQName; + } + } + return result; + } + /** * @param qname @@ -126,6 +150,26 @@ public abstract class DictionaryWebServiceBase extends DeclarativeWebScript } } + /** + * @param prefix prefix for classname as cm + * @param shorname the short class name as person + * @return String the full name in the following format {namespaceuri}shorname + */ + public String getFullNamespaceURI(String prefix, String shorname) + { + try + { + String result = null; + String url = this.namespaceService.getNamespaceURI(prefix); + result = "{" + url + "}" + shorname; + return result; + } + catch (Exception e) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "The exact classname - " + prefix + ":" + shorname + " parameter has not been provided in the URL"); + } + } + /** * @param classname - checks whether the classname is valid , gets the classname as input e.g cm_person * @return true - if the class is valid , false - if the class is invalid @@ -145,6 +189,27 @@ public abstract class DictionaryWebServiceBase extends DeclarativeWebScript return false; } + /** + * Checks whether the classname is valid + * @param prefix - gets the prefix as input e.g cm + * @param shorname - gets the short classname as input e.g person + * @return true - if the class is valid , false - if the class is invalid + */ + public boolean isValidClassname(String prefix, String shorname) + { + QName qname = null; + try + { + qname = QName.createQName(this.getFullNamespaceURI(prefix, shorname)); + return (dictionaryservice.getClass(qname) != null); + } + catch (InvalidQNameException e) + { + //just ignore + } + return false; + } + /** * @param namespaceprefix - gets a valid namespaceprefix as input * @return modelname from namespaceprefix - returns null if invalid namespaceprefix is given @@ -193,6 +258,26 @@ public abstract class DictionaryWebServiceBase extends DeclarativeWebScript return false; } + /** + * @param prefix as the input + * @param shorname as the input + * @return true if it is a aspect or false if it is a Type + */ + public boolean isValidTypeorAspect(String prefix, String shorname) + { + try + { + QName qname = QName.createQName(this.getFullNamespaceURI(prefix, shorname)); + return ((this.dictionaryservice.getClass(qname) != null) && + (this.dictionaryservice.getClass(qname).isAspect())); + } + catch (InvalidQNameException e) + { + // ignore + } + return false; + } + /** * @param modelname - gets the modelname as the input (modelname is without prefix ie. cm:contentmodel => where modelname = contentmodel) * @return true if valid or false @@ -269,4 +354,21 @@ public abstract class DictionaryWebServiceBase extends DeclarativeWebScript classfilter.equals(CLASS_FILTER_OPTION_TYPE3)); } + /** + * Returns dependent collections (properties or associations) + * in order that complies to order of class definitions + * @param sortedClassDefs - list of sorted class definitions + * @param dependent - collections that depend on class definitions + * @return collection of dependent values + */ + protected Collection reorderedValues(List sortedClassDefs, Map dependent) + { + Collection result = new ArrayList(sortedClassDefs.size()); + for (ClassDefinition classDef : sortedClassDefs) + { + result.add(dependent.get(classDef.getName())); + } + return result; + } + } diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/PropertiesGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/PropertiesGet.java index 1c8f8ff12e..63c54a3c33 100644 --- a/source/java/org/alfresco/repo/web/scripts/dictionary/PropertiesGet.java +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/PropertiesGet.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2012 Alfresco Software Limited. * * This file is part of Alfresco * @@ -18,38 +18,23 @@ */ package org.alfresco.repo.web.scripts.dictionary; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.namespace.QName; -import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptRequest; /** - * * Webscript to get the Propertydefinitions for a given classname eg. =>cm_person * - * @author Saravanan Sellathurai + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich */ -public class PropertiesGet extends DictionaryWebServiceBase +public class PropertiesGet extends AbstractPropertiesGet { - private static final String MODEL_PROP_KEY_PROPERTY_DETAILS = "propertydefs"; - private static final String DICTIONARY_CLASS_NAME = "classname"; - private static final String PARAM_NAME = "name"; - private static final String REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX = "nsp"; + private static final String DICTIONARY_CLASS_NAME = "classname"; - /** - * @Override method from DeclarativeWebScript - */ - protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + @Override + protected QName getClassQName(WebScriptRequest req) { QName classQName = null; String className = req.getServiceMatch().getTemplateVars().get(DICTIONARY_CLASS_NAME); @@ -62,71 +47,7 @@ public class PropertiesGet extends DictionaryWebServiceBase throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the className - " + className + " - parameter in the URL"); } } - - String[] names = req.getParameterValues(PARAM_NAME); - - String namespacePrefix = req.getParameter(REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX); - String namespaceURI = null; - if (namespacePrefix != null) - { - namespaceURI = this.namespaceService.getNamespaceURI(namespacePrefix); - } - - Map propMap = null; - if (classQName == null) - { - if (names != null) - { - propMap = new HashMap(names.length); - for (String name : names) - { - QName propQName = QName.createQName(name, namespaceService); - PropertyDefinition propDef = dictionaryservice.getProperty(propQName); - if (propDef != null) - { - propMap.put(propQName, propDef); - } - } - } - else - { - Collection propQNames = dictionaryservice.getAllProperties(null); - propMap = new HashMap(propQNames.size()); - for (QName propQName : propQNames) - { - propMap.put(propQName, dictionaryservice.getProperty(propQName)); - } - } - - } - else - { - // Get all the property definitions for the class - propMap = dictionaryservice.getClass(classQName).getProperties(); - } - - // Filter the properties by URI - List props = new ArrayList(propMap.size()); - for (Map.Entry entry : propMap.entrySet()) - { - if ((namespaceURI != null && - namespaceURI.equals(entry.getKey().getNamespaceURI()) == true) || - namespaceURI == null) - { - props.add(entry.getValue()); - } - } - - // Order property definitions by title - Collections.sort(props, new DictionaryComparators.PropertyDefinitionComparator()); - - // Pass list of property definitions to template - Map model = new HashMap(); - model.put(MODEL_PROP_KEY_PROPERTY_DETAILS, props); - return model; - + return classQName; } - - - -} \ No newline at end of file + +} diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/PropertyGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/PropertyGet.java index 04c5906025..4e9bba1b79 100644 --- a/source/java/org/alfresco/repo/web/scripts/dictionary/PropertyGet.java +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/PropertyGet.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2012 Alfresco Software Limited. * * This file is part of Alfresco * @@ -18,11 +18,7 @@ */ package org.alfresco.repo.web.scripts.dictionary; -import java.util.HashMap; -import java.util.Map; - import org.alfresco.service.namespace.QName; -import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptRequest; @@ -30,49 +26,39 @@ import org.springframework.extensions.webscripts.WebScriptRequest; /** * Webscript to get the Propertydefinition for a given classname and propname * - * @author Saravanan Sellathurai + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich */ -public class PropertyGet extends DictionaryWebServiceBase +public class PropertyGet extends AbstractPropertyGet { - private static final String MODEL_PROP_KEY_PROPERTY_DETAILS = "propertydefs"; - private static final String DICTIONARY_CLASS_NAME = "classname"; - private static final String DICTIONARY_PROPERTY_NAME = "propname"; + private static final String DICTIONARY_CLASS_NAME = "classname"; + private static final String DICTIONARY_PROPERTY_NAME = "propname"; - /** - * @Override method from DeclarativeWebScript - */ - protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + @Override + protected QName getPropertyQname(WebScriptRequest req) { - String className = req.getServiceMatch().getTemplateVars().get(DICTIONARY_CLASS_NAME); String propertyName = req.getServiceMatch().getTemplateVars().get(DICTIONARY_PROPERTY_NAME); - Map model = new HashMap(1); - QName classQname = null; - QName propertyQname = null; - - //validate the classname - if(isValidClassname(className) == false) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + className + " - parameter in the URL"); - } - - classQname = QName.createQName(getFullNamespaceURI(className)); - //validate the presence of property name if(propertyName == null) { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Missing parameter propertyname in the URL"); + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Missing parameter propertyname in the URL"); } - propertyQname = QName.createQName(getFullNamespaceURI(propertyName)); + return QName.createQName(getFullNamespaceURI(propertyName)); + } - if(this.dictionaryservice.getClass(classQname).getProperties().get(propertyQname) != null) - { - model.put(MODEL_PROP_KEY_PROPERTY_DETAILS, this.dictionaryservice.getClass(classQname).getProperties().get(propertyQname)); - } + @Override + protected QName getClassQname(WebScriptRequest req) + { + String className = req.getServiceMatch().getTemplateVars().get(DICTIONARY_CLASS_NAME); - return model; + // validate the classname + if (isValidClassname(className) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + className + " - parameter in the URL"); + } + return QName.createQName(getFullNamespaceURI(className)); } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/SubClassesGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/SubClassesGet.java index be7ee707c9..f3a79721c4 100644 --- a/source/java/org/alfresco/repo/web/scripts/dictionary/SubClassesGet.java +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/SubClassesGet.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2010 Alfresco Software Limited. + * Copyright (C) 2005-2012 Alfresco Software Limited. * * This file is part of Alfresco * @@ -18,18 +18,9 @@ */ package org.alfresco.repo.web.scripts.dictionary; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.alfresco.service.cmr.dictionary.AssociationDefinition; -import org.alfresco.service.cmr.dictionary.ClassDefinition; -import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.namespace.QName; -import org.springframework.extensions.webscripts.Cache; import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptRequest; @@ -37,139 +28,52 @@ import org.springframework.extensions.webscripts.WebScriptRequest; /** * Webscript to get the Sub-Classdefinitions using classfilter , namespacePrefix and name * - * @author Saravanan Sellathurai + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich */ -public class SubClassesGet extends DictionaryWebServiceBase +public class SubClassesGet extends AbstractSubClassesGet { - private static final String MODEL_PROP_KEY_CLASS_DEFS = "classdefs"; - private static final String MODEL_PROP_KEY_PROPERTY_DETAILS = "propertydefs"; - private static final String MODEL_PROP_KEY_ASSOCIATION_DETAILS = "assocdefs"; - - private static final String REQ_URL_TEMPL_IMMEDIATE_SUB_TYPE_CHILDREN = "r"; - //private static final String REQ_URL_TEMPL_VAR_CLASS_FILTER = "cf"; - private static final String REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX = "nsp"; - private static final String REQ_URL_TEMPL_VAR_NAME = "n"; private static final String DICTIONARY_CLASS_NAME = "classname"; - /** - * @Override method from DeclarativeWebScript - */ - protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + @Override + protected Collection getQNameCollection(WebScriptRequest req, boolean recursive) { - String name = req.getParameter(REQ_URL_TEMPL_VAR_NAME); - String namespacePrefix = req.getParameter(REQ_URL_TEMPL_VAR_NAMESPACE_PREFIX); - String className = req.getServiceMatch().getTemplateVars().get(DICTIONARY_CLASS_NAME); - String recursiveValue = getValidInput(req.getParameter(REQ_URL_TEMPL_IMMEDIATE_SUB_TYPE_CHILDREN)); - - boolean recursive = true; - - Map classdef = new HashMap(); - Map> propdef = new HashMap>(); - Map> assocdef = new HashMap>(); - Map model = new HashMap(); - QName classQName = null; - String namespaceUri = null; - Collection qname = null; boolean isAspect = false; - boolean ignoreCheck = false; - - // validate recursive parameter => can be either true or false or null - if(recursiveValue == null) - { - recursive = true; - } - else if(recursiveValue.equalsIgnoreCase("true")) - { - recursive = true; - } - else if (recursiveValue.equalsIgnoreCase("false")) - { - recursive = false; - } - else - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the value for the parameter recursive=> " + recursiveValue +" can only be either true or false"); - } + String className = req.getServiceMatch().getTemplateVars().get(DICTIONARY_CLASS_NAME); //validate the className if(isValidClassname(className) == true) { - classQName = QName.createQName(getFullNamespaceURI(className)); - if(isValidTypeorAspect(className) == true) - { - isAspect = true; - } + classQName = QName.createQName(getFullNamespaceURI(className)); + if(isValidTypeorAspect(className) == true) + { + isAspect = true; + } } else { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the className - " + className + " parameter in the URL"); + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the className - " + className + " parameter in the URL"); } // collect the subaspects or subtypes of the class if(isAspect == true) - { - qname = this.dictionaryservice.getSubAspects(classQName, recursive); + { + return this.dictionaryservice.getSubAspects(classQName, recursive); } else - { - qname = this.dictionaryservice.getSubTypes(classQName, recursive); - } - - //validate the name parameter - if(name != null) { - if(isValidModelName(name) == false) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the name parameter - " + name + " in the URL"); - } + return this.dictionaryservice.getSubTypes(classQName, recursive); } + } - //validate the name parameter - if (namespacePrefix == null && name != null) + @Override + protected void validateClassname(String namespacePrefix, String name) + { + if(isValidClassname(namespacePrefix + "_" + name) == false) { - namespaceUri = namespaceService.getNamespaceURI(getPrefixFromModelName(name)); + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the namespacePrefix - " + namespacePrefix + " and name - "+ name + " - parameter in the URL"); } - - if (namespacePrefix != null && name == null) - { - namespaceUri = namespaceService.getNamespaceURI(namespacePrefix); - } - - if(namespacePrefix == null && name == null) - { - namespaceUri = null; - ignoreCheck = true; - } - - if (namespacePrefix != null && name != null) - { - if(isValidClassname(namespacePrefix + "_" + name) == false) - { - throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the namespacePrefix - " + namespacePrefix + " and name - "+ name + " - parameter in the URL"); - } - namespaceUri = namespaceService.getNamespaceURI(namespacePrefix); - } - - for(QName qnameObj: qname) - { - if((ignoreCheck == true) || - (qnameObj.getNamespaceURI().equals(namespaceUri))) - { - classdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj)); - propdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj).getProperties().values()); - assocdef.put(qnameObj, this.dictionaryservice.getClass(qnameObj).getAssociations().values()); - } - } - - List classDefinitions = new ArrayList(classdef.values()); - Collections.sort(classDefinitions, new DictionaryComparators.ClassDefinitionComparator()); - model.put(MODEL_PROP_KEY_CLASS_DEFS, classDefinitions); - model.put(MODEL_PROP_KEY_PROPERTY_DETAILS, propdef.values()); - model.put(MODEL_PROP_KEY_ASSOCIATION_DETAILS, assocdef.values()); - return model; - - } + } - } \ No newline at end of file +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/AssociationGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/AssociationGet.java new file mode 100644 index 0000000000..e92c60e35d --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/AssociationGet.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary.prefixed; + +import org.alfresco.repo.web.scripts.dictionary.AbstractAssociationGet; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/* + * Webscript to get the Associationdefinition for a given classname and association-name + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public class AssociationGet extends AbstractAssociationGet +{ + private static final String DICTIONARY_PREFIX = "prefix"; + private static final String DICTIONARY_SHORT_CLASS_NAME = "shortClassName"; + private static final String DICTIONARY_ASSOCIATION_PREFIX = "assocprefix"; + private static final String DICTIONARY_ASSOCIATION_SHORTNAME = "assocname"; + + @Override + protected QName getClassQname(WebScriptRequest req) + { + String classPrefix = req.getServiceMatch().getTemplateVars().get(DICTIONARY_PREFIX); + String shortClassName = req.getServiceMatch().getTemplateVars().get(DICTIONARY_SHORT_CLASS_NAME); + + //validate the classname + if(isValidClassname(classPrefix, shortClassName) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + classPrefix + ":" + shortClassName + " - parameter in the URL"); + } + + return QName.createQName(getFullNamespaceURI(classPrefix, shortClassName)); + } + + @Override + protected QName getAssociationQname(WebScriptRequest req) + { + String associationName = req.getServiceMatch().getTemplateVars().get(DICTIONARY_ASSOCIATION_SHORTNAME); + String associationPrefix = req.getServiceMatch().getTemplateVars().get(DICTIONARY_ASSOCIATION_PREFIX); + + if(associationPrefix == null) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Missing parameter association prefix in the URL"); + } + if(associationName == null) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Missing parameter association name in the URL"); + } + + return QName.createQName(getFullNamespaceURI(associationPrefix, associationName)); + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/AssociationsGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/AssociationsGet.java new file mode 100644 index 0000000000..11e764d2a1 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/AssociationsGet.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary.prefixed; + +import org.alfresco.repo.web.scripts.dictionary.AbstractAssociationsGet; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Webscript to get the Associationdefinitions for a given classname + * + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public class AssociationsGet extends AbstractAssociationsGet +{ + private static final String DICTIONARY_PREFIX = "prefix"; + private static final String DICTIONARY_SHORT_CLASS_NAME = "shortClassName"; + + @Override + protected QName getClassQname(WebScriptRequest req) + { + String prefix = req.getServiceMatch().getTemplateVars().get(DICTIONARY_PREFIX); + String shortClassName = req.getServiceMatch().getTemplateVars().get(DICTIONARY_SHORT_CLASS_NAME); + + //validate classname + if (isValidClassname(prefix, shortClassName) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + prefix + ":" + shortClassName + " - parameter in the URL"); + } + return QName.createQName(getFullNamespaceURI(prefix, shortClassName)); + } + + @Override + protected QName getAssociationQname(String namespacePrefix, String name) + { + return QName.createQName(getFullNamespaceURI(namespacePrefix, name)); + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/ClassGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/ClassGet.java new file mode 100644 index 0000000000..91db3df1d5 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/ClassGet.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary.prefixed; + +import org.alfresco.repo.web.scripts.dictionary.AbstractClassGet; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Webscript to get the Classdefinitions for a classname eg. =>cm_author + * + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public class ClassGet extends AbstractClassGet +{ + private static final String DICTIONARY_PREFIX = "prefix"; + private static final String DICTIONARY_SHORT_CLASS_NAME = "shortClassName"; + + /** + * @Override method from AbstractClassGet + */ + @Override + protected QName getClassQname(WebScriptRequest req) + { + String prefix = req.getServiceMatch().getTemplateVars().get(DICTIONARY_PREFIX); + String shortName = req.getServiceMatch().getTemplateVars().get(DICTIONARY_SHORT_CLASS_NAME); + + //validate the classname and throw appropriate error message + if (isValidClassname(prefix, shortName) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + prefix + ":" + shortName + " - parameter in the URL"); + } + return QName.createQName(getFullNamespaceURI(prefix, shortName)); + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/ClassesGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/ClassesGet.java new file mode 100644 index 0000000000..ed4e70ecba --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/ClassesGet.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary.prefixed; + +import org.alfresco.repo.web.scripts.dictionary.AbstractClassesGet; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; + +/** + * Webscript to get the Classdefinitions using classfilter , namespaceprefix and name + * + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public class ClassesGet extends AbstractClassesGet +{ + @Override + protected QName getQNameForModel(String namespacePrefix, String name) + { + return QName.createQName(getFullNamespaceURI(namespacePrefix, name)); + } + + @Override + protected QName getClassQname(String namespacePrefix, String name) + { + if(isValidClassname(namespacePrefix, name) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the name - " + name + "parameter in the URL"); + } + return QName.createQName(getFullNamespaceURI(namespacePrefix, name)); + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/DictionaryRestApiTest.java b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/DictionaryRestApiTest.java new file mode 100644 index 0000000000..bb3ddeffce --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/DictionaryRestApiTest.java @@ -0,0 +1,1022 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary.prefixed; + +import org.alfresco.repo.web.scripts.BaseWebScriptTest; +import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest; +import org.springframework.extensions.webscripts.TestWebScriptServer.Response; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.json.JSONObject; +import org.json.JSONArray; + +/** + * Unit test for Dictionary REST API + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public class DictionaryRestApiTest extends BaseWebScriptTest +{ + private static final String URL_SITES = "/api/defclasses"; + private static final String URL_PROPERTIES = "/api/defproperties"; + + @Override + protected void setUp() throws Exception + { + super.setUp(); + } + + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + } + + private void validatePropertyDef(JSONObject result) throws Exception + { + assertEquals("cm:created", result.get("name")); + assertEquals("Created Date", result.get("title")); + assertEquals("Created Date", result.get("description")); + assertEquals("d:datetime", result.get("dataType")); + assertEquals(false, result.get("multiValued")); + assertEquals(true, result.get("mandatory")); + assertEquals(true, result.get("enforced")); + assertEquals(true, result.get("protected")); + assertEquals(true, result.get("indexed")); + assertEquals(true, result.get("indexedAtomically")); + assertEquals("/api/property/cm/created", result.get("url")); + + } + + private void validateChildAssociation(JSONObject result) throws Exception + { + assertEquals("wca:formworkflowdefaults", result.get("name")); + assertEquals("Form Workflow Defaults", result.get("title")); + assertEquals("Form Workflow Defaults", result.get("description")); + assertEquals(true, result.get("isChildAssociation")); + assertEquals(false, result.get("protected")); + + assertEquals("wca:form", result.getJSONObject("source").get("class")); + assertEquals(false, result.getJSONObject("source").get("mandatory")); + assertEquals(false, result.getJSONObject("source").get("many")); + + assertEquals("wca:workflowdefaults", result.getJSONObject("target").get("class")); + assertEquals(false, result.getJSONObject("target").get("mandatory")); + assertEquals(false, result.getJSONObject("target").get("many")); + + assertEquals("/api/defclasses/wca/form/association/wca/formworkflowdefaults", result.get("url")); + } + + private void validateAssociation(JSONObject result) throws Exception + { + assertEquals("wca:renderingenginetemplates", result.get("name")); + assertEquals("Rendering Engine Templates", result.get("title")); + assertEquals("Rendering Engine Templates", result.get("description")); + assertEquals(false, result.get("isChildAssociation")); + assertEquals(false, result.get("protected")); + + assertEquals("wca:form", result.getJSONObject("source").get("class")); + assertEquals("wca:capture", result.getJSONObject("source").get("role")); + assertEquals(false, result.getJSONObject("source").get("mandatory")); + assertEquals(false, result.getJSONObject("source").get("many")); + + assertEquals("wca:renderingenginetemplate", result.getJSONObject("target").get("class")); + assertEquals("wca:presentation", result.getJSONObject("target").get("role")); + assertEquals(false, result.getJSONObject("target").get("mandatory")); + assertEquals(true, result.getJSONObject("target").get("many")); + + assertEquals("/api/defclasses/wca/form/association/wca/renderingenginetemplates", result.get("url")); + } + private void validateAssociationDef(JSONObject result) throws Exception + { + assertEquals("cm:avatar", result.get("name")); + assertEquals("Avatar", result.get("title")); + assertEquals("The person's avatar image", result.get("description")); + assertEquals(false, result.get("isChildAssociation")); + assertEquals(false, result.get("protected")); + + assertEquals("cm:person", result.getJSONObject("source").get("class")); + assertEquals("cm:avatarOf", result.getJSONObject("source").get("role")); + assertEquals(false, result.getJSONObject("source").get("mandatory")); + assertEquals(false, result.getJSONObject("source").get("many")); + + assertEquals("cm:content", result.getJSONObject("target").get("class")); + assertEquals("cm:hasAvatar", result.getJSONObject("target").get("role")); + assertEquals(false, result.getJSONObject("target").get("mandatory")); + assertEquals(false, result.getJSONObject("target").get("many")); + + assertEquals("/api/defclasses/cm/person/association/cm/avatar", result.get("url")); + } + + private void validateTypeClass(JSONObject result) throws Exception + { + //cm:cmobject is of type =>type + assertEquals("cm:cmobject", result.get("name")); + assertEquals(false , result.get("isAspect")); + assertEquals("Object", result.get("title")); + assertEquals("", result.get("description")); + + assertEquals("sys:base", result.getJSONObject("parent").get("name")); + assertEquals("base", result.getJSONObject("parent").get("title")); + assertEquals("/api/defclasses/sys/base", result.getJSONObject("parent").get("url")); + + assertEquals("sys:referenceable", result.getJSONObject("defaultAspects").getJSONObject("sys:referenceable").get("name")); + assertEquals("Referenceable", result.getJSONObject("defaultAspects").getJSONObject("sys:referenceable").get("title")); + assertEquals("/api/defclasses/cm/cmobject/property/sys/referenceable", result.getJSONObject("defaultAspects").getJSONObject("sys:referenceable").get("url")); + + assertEquals("cm:auditable", result.getJSONObject("defaultAspects").getJSONObject("cm:auditable").get("name")); + assertEquals("Auditable", result.getJSONObject("defaultAspects").getJSONObject("cm:auditable").get("title")); + assertEquals("/api/defclasses/cm/cmobject/property/cm/auditable", result.getJSONObject("defaultAspects").getJSONObject("cm:auditable").get("url")); + + //assertEquals("cm:name", result.getJSONObject("properties").getJSONObject("cm:name").get("name")); + //assertEquals("Name", result.getJSONObject("properties").getJSONObject("cm:name").get("title")); + //assertEquals("/api/defclasses/cm/cmobject/property/cm/name", result.getJSONObject("properties").getJSONObject("cm:name").get("url")); + + //assertEquals(, result.getJSONObject("associations").length()); + //assertEquals(0, result.getJSONObject("childassociations").length()); + + assertEquals("/api/defclasses/cm/cmobject", result.get("url")); + + } + + private void validateAspectClass(JSONObject result) throws Exception + { + //cm:thumbnailed is of type =>aspect + assertEquals("cm:thumbnailed", result.get("name")); + assertEquals(true , result.get("isAspect")); + assertEquals("Thumbnailed", result.get("title")); + assertEquals("", result.get("description")); + assertEquals(0, result.getJSONObject("defaultAspects").length()); + + if (result.getJSONObject("properties").has("cm:automaticUpdate") == true) + { + assertEquals("cm:automaticUpdate", result.getJSONObject("properties").getJSONObject("cm:automaticUpdate").get("name")); + assertEquals("Automatic Update", result.getJSONObject("properties").getJSONObject("cm:automaticUpdate").get("title")); + assertEquals("/api/defclasses/cm/thumbnailed/property/cm/automaticUpdate", result.getJSONObject("properties").getJSONObject("cm:automaticUpdate").get("url")); + } + + //assertEquals(2, result.getJSONObject("associations").length()); + } + + private void validatePropertiesConformity(JSONArray classDefs) throws Exception + { + final int itemsToTest = 10; + for (int i = 0; (i < itemsToTest) && (i < classDefs.length()); ++i) + { + JSONObject classDef1 = classDefs.getJSONObject(i); + JSONArray propertyNames1 = classDef1.getJSONObject("properties").names(); + // properties of class obtained by api/defclasses + List propertyValues1 = Collections.emptyList(); + if (propertyNames1 != null) + { + propertyValues1 = new ArrayList(propertyNames1.length()); + for (int j = 0; j < propertyNames1.length(); j++) + { + propertyValues1.add(propertyNames1.getString(j)); + } + } + + String classUrl = classDef1.getString("url"); + assertTrue(classUrl.contains(URL_SITES)); + Response responseFromGetClassDef = sendRequest(new GetRequest(classUrl), 200); + JSONObject classDef2 = new JSONObject(responseFromGetClassDef.getContentAsString()); + assertTrue(classDef2.length() > 0); + assertEquals(200, responseFromGetClassDef.getStatus()); + assertEquals(classDef1.getString("name"), classDef2.getString("name")); + JSONArray propertyNames2 = classDef2.getJSONObject("properties").names(); + // properties of class obtained by api/defclasses/class + List propertyValues2 = Collections.emptyList(); + if (propertyNames2 != null) + { + propertyValues2 = new ArrayList(propertyNames2.length()); + for (int j = 0; j < propertyNames2.length(); j++) + { + propertyValues2.add(propertyNames2.getString(j)); + } + } + + Response responseFromGetPropertiesDef = sendRequest(new GetRequest(classUrl + "/properties"), 200); + JSONArray propertiesDefs = new JSONArray(responseFromGetPropertiesDef.getContentAsString()); + assertEquals(200, responseFromGetClassDef.getStatus()); + // properties of class obtained by api/defclasses/class/properties + List propertyValues3 = new ArrayList(propertiesDefs.length()); + for (int j = 0; j < propertiesDefs.length(); j++) + { + propertyValues3.add(propertiesDefs.getJSONObject(j).getString("name")); + } + + assertEquivalenceProperties(propertyValues1, propertyValues2); + assertEquivalenceProperties(propertyValues2, propertyValues3); + } + } + + private void assertEquivalenceProperties(List propertyValues1, List propertyValues2) + { + if ((propertyValues1.size() != propertyValues2.size()) || !propertyValues1.containsAll(propertyValues2)) + { + fail("Wrong properties in classes"); + } + } + + public void testGetPropertyDef() throws Exception + { + Response response = sendRequest(new GetRequest("/api/defclasses/cm/auditable/property/cm/created"), 200); + assertEquals(200,response.getStatus()); + JSONObject result = new JSONObject(response.getContentAsString()); + validatePropertyDef(result); + + assertEquals(result.length()>0, true); + response = sendRequest(new GetRequest("/api/defclasses/cm/hi/property/cm/welcome"), 404); + assertEquals(404,response.getStatus()); + + //invalid property name , returns a null JsonObject as such a property doesn't exist under cm_auditable + response = sendRequest(new GetRequest("/api/defclasses/cm/auditable/property/cm/welcome"), 200); + result = new JSONObject(response.getContentAsString()); + assertEquals(0, result.length()); + assertEquals(200,response.getStatus()); + } + + public void testGetPropertyDefs() throws Exception + { + //validate for a particular property cm_created in the class cm_auditable + GetRequest req = new GetRequest(URL_SITES + "/cm/auditable/properties"); + Map< String, String > arguments = new HashMap< String, String >(); + arguments.put("nsp", "cm"); + req.setArgs(arguments); + Response response = sendRequest(req, 200); + assertEquals(200,response.getStatus()); + + JSONArray result = new JSONArray(response.getContentAsString()); + assertEquals(200,response.getStatus()); + assertEquals(5, result.length()); + + //validate with no parameter => returns an array of property definitions + arguments.clear(); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(200,response.getStatus()); + assertEquals(result.length()>0, true); + for(int i=0; i0, true); + for (int i = 0; i < result.length(); i++) + { + if(result.getJSONObject(i).get("name").equals("cm:created")) + { + validatePropertyDef(result.getJSONObject(i)); + } + + String title = ""; + if (result.getJSONObject(i).has("title") == true) + { + title = result.getJSONObject(i).getString("title"); + } + System.out.println(title + " - " + result.getJSONObject(i).getString("name")); + } + +// System.out.println("/n/n"); + + // test /api/properties?name=cm:name&name=cm:title&name=cm:description + req = new GetRequest(URL_PROPERTIES + "?name=cm:name&name=cm:title&name=cm:description"); + response = sendRequest(req, 200); + assertEquals(200, response.getStatus()); + result = new JSONArray(response.getContentAsString()); + assertEquals(3, result.length()); +// for (int i = 0; i < result.length(); i++) +// { +// String title = ""; +// if (result.getJSONObject(i).has("title") == true) +// { +// title = result.getJSONObject(i).getString("title"); +// } +// System.out.println(title + " - " + result.getJSONObject(i).getString("name")); +// } + + + } + + public void testGetClassDetail() throws Exception + { + GetRequest req = new GetRequest(URL_SITES + "/cm/thumbnailed"); + Response response = sendRequest(req, 200); + JSONObject result = new JSONObject(response.getContentAsString()); + assertEquals(result.length()>0, true); + assertEquals(200,response.getStatus()); + validateAspectClass(result); + + req = new GetRequest(URL_SITES + "/cm/cmobject"); + response = sendRequest(req, 200); + result = new JSONObject(response.getContentAsString()); + assertEquals(result.length()>0, true); + assertEquals(200,response.getStatus()); + validateTypeClass(result); + + response = sendRequest(new GetRequest("/api/defclasses/cm/hi"), 404); + assertEquals(404,response.getStatus()); + } + + + public void testGetClassDetails() throws Exception + { + /** + * There are eight scenarios with getting class details , all are optional fields + * Classfilter namespaceprefix name Returns + * 1 yes yes yes single class + * 2 yes yes no Array of classes [returns array of classes of the particular namespaceprefix] + * 3 yes no no Array of classes [depends on classfilter, either type or aspect or all classes in the repo] + * 4 no no no Array of classes [returns all classes of both type and aspects in the entire repository] + * 5 no yes yes single class [returns a single class of a valid namespaceprefix:name combination] + * 6 no yes no Array of classes [returns an array of all aspects and types under particular namespaceprefix] + * 7 no no yes 404 error [since name alone doesn't makes any meaning] + * 8 yes no yes 404 error [since name alone doesn't makes any meaning] + * Test cases are provided for all the above scenarios + */ + + + //check for a aspect under cm with name thumbnailes [case-type:1] + GetRequest req = new GetRequest(URL_SITES); + Map< String, String > arguments = new HashMap< String, String >(); + arguments.put("cf", "aspect"); + arguments.put("nsp", "cm"); + arguments.put("n", "thumbnailed"); + req.setArgs(arguments); + Response response = sendRequest(req, 200); + JSONArray result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; i0, true); + for(int i=0; i0, true); + for(int i=0; iname, namespaceprefix [case-type:2] + arguments.clear(); + arguments.put("cf", "type"); + arguments.put("nsp", "cm"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + // the above result has all the types under cm, so now check for the presence type cm:cmobject in the array of classes of all types + for(int i=0; iname [case-type:2] + arguments.clear(); + arguments.put("cf", "aspect"); + arguments.put("nsp", "cm"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + // the above result has all the aspects under cm, so now check for the presence aspect cm:thumnailed in the array of classes of all aspects + for(int i=0; iname [case-type:2] + arguments.clear(); + arguments.put("cf", "all"); + arguments.put("nsp", "cm"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; iname, namespaceprefix [case-type:3] + arguments.clear(); + arguments.put("cf", "type"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; iname, namespaceprefix [case-type:3] + arguments.clear(); + arguments.put("cf", "aspect"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; i0, true); + for(int i=0; i0, true); + for(int i=0; i cm:cmobject] without classfilter option [case-type:5] + arguments.clear(); + arguments.put("nsp", "cm"); + arguments.put("n", "cmobject"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; i cm:thumbnailed] without classfilter option [case-type:5] + arguments.clear(); + arguments.put("nsp", "cm"); + arguments.put("n", "thumbnailed"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; i cm] without classfilter and name option [case-type:6] + arguments.clear(); + arguments.put("nsp", "cm"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; i cm] without classfilter and name option [case-type:6] + arguments.clear(); + arguments.put("nsp", "cm"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; i cm] without classfilter and name option [case-type:6] + arguments.clear(); + arguments.put("nsp", "cm"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; i returns 404 error + arguments.clear(); + arguments.put("n", "cmobject"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + + //check for a type under cm with name cmobject and no namespaceprefix [case-type:8] => returns 404 error + arguments.clear(); + arguments.put("cf", "type"); + arguments.put("n", "cmobject"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + // Test with wrong data + //check for all aspects under cm without option=>name + arguments.clear(); + arguments.put("cf", "aspects"); + arguments.put("nsp", "cm"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + //check for all types under cm without option=>name + arguments.clear(); + arguments.put("cf", "types"); + arguments.put("nsp", "cmd"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + //check for all dictionary data without option=>name and option=>namespaceprefix + arguments.clear(); + arguments.put("cf", "a�&llsara"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + //check for all aspect dictionary data without option=>name and option=>namespaceprefix + arguments.clear(); + arguments.put("cf", "aspectb"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + //check for all types dictionary data without option=>name and option=>namespaceprefix + arguments.clear(); + arguments.put("cf", "typesa"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + //check for all types dictionary data without option=>name and option=>namespaceprefix and option=>classfilter + arguments.clear(); + req.setArgs(arguments); + response = sendRequest(req, 200); + assertEquals(200,response.getStatus()); + } + + public void testSubClassDetails() throws Exception + { + GetRequest req = new GetRequest(URL_SITES + "/sys/base/subclasses"); + Map< String, String > arguments = new HashMap< String, String >(); + arguments.put("r", "true"); + req.setArgs(arguments); + Response response = sendRequest(req, 200); + assertEquals(200,response.getStatus()); + response = sendRequest(req, 200); + JSONArray result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; i0, true); + for(int i=0; i0, true); + for(int i=0; i0, true); + for(int i=0; iall and classname=>wca_form + GetRequest req = new GetRequest(URL_SITES + "/wca/form/associations"); + Map< String, String > arguments = new HashMap< String, String >(); + arguments.put("af", "all"); + req.setArgs(arguments); + Response response = sendRequest(req, 200); + JSONArray result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; ichild and classname=>wca_form + arguments.clear(); + arguments.put("af", "child"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; igeneral(that means an association and not child) and classname=>wca_form + arguments.clear(); + arguments.put("af", "general"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; i returns a single valid class + arguments.clear(); + arguments.put("af", "general"); + arguments.put("nsp", "wca"); + arguments.put("n", "renderingenginetemplates"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; ireturns a single valid class + arguments.clear(); + arguments.put("af", "child"); + arguments.put("nsp", "wca"); + arguments.put("n", "formworkflowdefaults"); + req.setArgs(arguments); + response = sendRequest(req, 200); + result = new JSONArray(response.getContentAsString()); + assertEquals(result.length()>0, true); + for(int i=0; i0, true); + for(int i=0; iboth name and namespaceprefix are needed + arguments.clear(); + arguments.put("af", "child"); + arguments.put("nsp", "wca"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + arguments.clear(); + arguments.put("af", "child"); + arguments.put("n", "renderingenginetemplates"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + arguments.clear(); + arguments.put("af", "general"); + arguments.put("n", "formworkflowdefaults"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + //look for associations (excluding child assocs) in the class wca_form , with no name parameter + arguments.clear(); + arguments.put("af", "general"); + arguments.put("nsp", "wca"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + //wrong data + response = sendRequest(new GetRequest(URL_SITES +"/cmsa/personalbe/associations"), 404); + assertEquals(404,response.getStatus()); + + //ask for a child-association which is actually not a valid child of classname - wca_form + arguments.clear(); + arguments.put("af", "child"); + arguments.put("nsp", "wca"); + arguments.put("n", "renderingenginetemplates"); + req.setArgs(arguments); + response = sendRequest(req, 200); + assertEquals(200,response.getStatus()); + + arguments.clear(); + arguments.put("af", "general"); + arguments.put("nsp", "wca"); // invalid namespaceprefix => should be of class-type wca + arguments.put("n", "renderingenginetemplates"); + req.setArgs(arguments); + response = sendRequest(req, 200); + assertEquals(200,response.getStatus()); + + //data without name parameter + arguments.clear(); + arguments.put("nsp", "cm"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + //data with invalid association in wca_form + arguments.clear(); + arguments.put("nsp", "wca"); + arguments.put("n", "dublincore"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + //data with invalid association in wca_form + arguments.clear(); + arguments.put("nsp", "cm"); + arguments.put("n", "hiwelcome"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + + //data with invalid class in wca_form + arguments.clear(); + arguments.put("nsp", "wca"); + arguments.put("n", "dublincore"); + req.setArgs(arguments); + response = sendRequest(req, 404); + assertEquals(404,response.getStatus()); + } + + public void testGetClasses() throws Exception + { + GetRequest req = new GetRequest(URL_SITES); + Response response = sendRequest(req, 200); + JSONArray result = new JSONArray(response.getContentAsString()); + + assertTrue(result.length() > 0); + assertEquals(200, response.getStatus()); + validatePropertiesConformity(result); + } + +} diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/PropertiesGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/PropertiesGet.java new file mode 100644 index 0000000000..f044e52302 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/PropertiesGet.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary.prefixed; + +import org.alfresco.repo.web.scripts.dictionary.AbstractPropertiesGet; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Webscript to get the Propertydefinitions for a given classname eg. =>cm_person + * + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public class PropertiesGet extends AbstractPropertiesGet +{ + private static final String DICTIONARY_PREFIX = "prefix"; + private static final String DICTIONARY_SHORT_CLASS_NAME = "shortClassName"; + + @Override + protected QName getClassQName(WebScriptRequest req) + { + QName classQName = null; + String prefix = req.getServiceMatch().getTemplateVars().get(DICTIONARY_PREFIX); + String shortName = req.getServiceMatch().getTemplateVars().get(DICTIONARY_SHORT_CLASS_NAME); + if (prefix != null && prefix.length() != 0 && shortName != null && shortName.length()!= 0) + { + classQName = createClassQName(prefix, shortName); + if (classQName == null) + { + // Error + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the className - " + prefix + ":" + shortName + " - parameter in the URL"); + } + } + return classQName; + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/PropertyGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/PropertyGet.java new file mode 100644 index 0000000000..b6281fd9aa --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/PropertyGet.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary.prefixed; + +import org.alfresco.repo.web.scripts.dictionary.AbstractPropertyGet; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Webscript to get the Propertydefinition for a given classname and propname + * + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public class PropertyGet extends AbstractPropertyGet +{ + private static final String DICTIONARY_PREFIX = "prefix"; + private static final String DICTIONARY_SHORT_CLASS_NAME = "shortClassName"; + private static final String DICTIONARY_SHORTPROPERTY_NAME = "propname"; + private static final String DICTIONARY_PROPERTY_FREFIX = "proppref"; + + @Override + protected QName getPropertyQname(WebScriptRequest req) + { + String propertyName = req.getServiceMatch().getTemplateVars().get(DICTIONARY_SHORTPROPERTY_NAME); + String propertyPrefix = req.getServiceMatch().getTemplateVars().get(DICTIONARY_PROPERTY_FREFIX); + + //validate the presence of property name + if(propertyName == null) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Missing parameter short propertyname in the URL"); + } + //validate the presence of property prefix + if(propertyPrefix == null) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Missing parameter propertyprefix in the URL"); + } + + return QName.createQName(getFullNamespaceURI(propertyPrefix, propertyName)); + } + + @Override + protected QName getClassQname(WebScriptRequest req) + { + String prefix = req.getServiceMatch().getTemplateVars().get(DICTIONARY_PREFIX); + String shortClassName = req.getServiceMatch().getTemplateVars().get(DICTIONARY_SHORT_CLASS_NAME); + + // validate the classname + if (isValidClassname(prefix, shortClassName) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the classname - " + prefix + ":" + shortClassName + " - parameter in the URL"); + } + + return QName.createQName(getFullNamespaceURI(prefix, shortClassName)); + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/SubClassesGet.java b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/SubClassesGet.java new file mode 100644 index 0000000000..598659e317 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/dictionary/prefixed/SubClassesGet.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2005-2012 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.web.scripts.dictionary.prefixed; + +import java.util.Collection; + +import org.alfresco.repo.web.scripts.dictionary.AbstractSubClassesGet; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * Webscript to get the Sub-Classdefinitions using classfilter , namespacePrefix and name + * @author Saravanan Sellathurai, Viachaslau Tsikhanovich + */ + +public class SubClassesGet extends AbstractSubClassesGet +{ + private static final String DICTIONARY_PREFIX = "prefix"; + private static final String DICTIONARY_CLASS_SHORTNAME = "shortClassName"; + + @Override + protected Collection getQNameCollection(WebScriptRequest req, boolean recursive) + { + String prefix = req.getServiceMatch().getTemplateVars().get(DICTIONARY_PREFIX); + String shortClassName = req.getServiceMatch().getTemplateVars().get(DICTIONARY_CLASS_SHORTNAME); + QName classQName = null; + boolean isAspect = false; + + //validate the className + if(isValidClassname(prefix, shortClassName) == true) + { + classQName = QName.createQName(getFullNamespaceURI(prefix, shortClassName)); + if(isValidTypeorAspect(prefix, shortClassName) == true) + { + isAspect = true; + } + } + else + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the className - " + prefix + ":" + shortClassName + " parameter in the URL"); + } + + // collect the subaspects or subtypes of the class + if(isAspect == true) + { + return this.dictionaryservice.getSubAspects(classQName, recursive); + } + else + { + return this.dictionaryservice.getSubTypes(classQName, recursive); + } + } + + @Override + protected void validateClassname(String namespacePrefix, String name) + { + if(isValidClassname(namespacePrefix, name) == false) + { + throw new WebScriptException(Status.STATUS_NOT_FOUND, "Check the namespacePrefix - " + namespacePrefix + " and name - "+ name + " - parameter in the URL"); + } + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java index 95256d04b5..e3ff0cbb0e 100644 --- a/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java +++ b/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java @@ -620,7 +620,7 @@ public abstract class BaseKerberosAuthenticationFilter extends BaseSSOAuthentica // Force the logon to start again resp.setHeader("WWW-Authenticate", "Negotiate"); resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - writeLoginPageLink(req, resp); + writeLoginPageLink(context, req, resp); resp.flushBuffer(); } diff --git a/source/java/org/alfresco/repo/webdav/auth/BaseNTLMAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/BaseNTLMAuthenticationFilter.java index 39b5bce74b..6483bc906c 100644 --- a/source/java/org/alfresco/repo/webdav/auth/BaseNTLMAuthenticationFilter.java +++ b/source/java/org/alfresco/repo/webdav/auth/BaseNTLMAuthenticationFilter.java @@ -267,7 +267,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication // Send back a request for NTLM authentication sresp.setHeader(WWW_AUTHENTICATE, AUTH_NTLM); sresp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - writeLoginPageLink(sreq, sresp); + writeLoginPageLink(context, sreq, sresp); sresp.flushBuffer(); return false; } @@ -1033,7 +1033,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication // Force the logon to start again res.setHeader(WWW_AUTHENTICATE, AUTH_NTLM); res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - writeLoginPageLink(req, res); + writeLoginPageLink(context, req, res); } res.flushBuffer(); } diff --git a/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java index 697ffee0ff..b47e7bdc26 100644 --- a/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java +++ b/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java @@ -522,12 +522,13 @@ public abstract class BaseSSOAuthenticationFilter extends BaseAuthenticationFilt /** * Writes link to login page and refresh tag which cause user * to be redirected to the login page. - * + * + * @param context ServletContext * @param resp HttpServletResponse * @param httpSess HttpSession * @throws IOException */ - protected void writeLoginPageLink(HttpServletRequest req, HttpServletResponse resp) throws IOException + protected void writeLoginPageLink(ServletContext context, HttpServletRequest req, HttpServletResponse resp) throws IOException { if ( hasLoginPage()) {