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()) {