diff --git a/project-build.xml b/project-build.xml index 430c6f7e7e..a2e8ee2cba 100644 --- a/project-build.xml +++ b/project-build.xml @@ -48,7 +48,7 @@ - + @@ -94,6 +94,20 @@ + + + + + + + + + + + + + + diff --git a/source/generated/org/alfresco/repo/webservice/dictionary/ClassPredicate.java b/source/generated/org/alfresco/repo/webservice/dictionary/ClassPredicate.java new file mode 100644 index 0000000000..68e58d812a --- /dev/null +++ b/source/generated/org/alfresco/repo/webservice/dictionary/ClassPredicate.java @@ -0,0 +1,201 @@ +/** + * ClassPredicate.java + * + * This file was auto-generated from WSDL + * by the Apache Axis 1.3 Oct 05, 2005 (05:23:37 EDT) WSDL2Java emitter. + */ + +package org.alfresco.repo.webservice.dictionary; + +public class ClassPredicate implements java.io.Serializable { + private java.lang.String[] names; + + private boolean followSubClass; + + private boolean followSuperClass; + + public ClassPredicate() { + } + + public ClassPredicate( + java.lang.String[] names, + boolean followSubClass, + boolean followSuperClass) { + this.names = names; + this.followSubClass = followSubClass; + this.followSuperClass = followSuperClass; + } + + + /** + * Gets the names value for this ClassPredicate. + * + * @return names + */ + public java.lang.String[] getNames() { + return names; + } + + + /** + * Sets the names value for this ClassPredicate. + * + * @param names + */ + public void setNames(java.lang.String[] names) { + this.names = names; + } + + public java.lang.String getNames(int i) { + return this.names[i]; + } + + public void setNames(int i, java.lang.String _value) { + this.names[i] = _value; + } + + + /** + * Gets the followSubClass value for this ClassPredicate. + * + * @return followSubClass + */ + public boolean isFollowSubClass() { + return followSubClass; + } + + + /** + * Sets the followSubClass value for this ClassPredicate. + * + * @param followSubClass + */ + public void setFollowSubClass(boolean followSubClass) { + this.followSubClass = followSubClass; + } + + + /** + * Gets the followSuperClass value for this ClassPredicate. + * + * @return followSuperClass + */ + public boolean isFollowSuperClass() { + return followSuperClass; + } + + + /** + * Sets the followSuperClass value for this ClassPredicate. + * + * @param followSuperClass + */ + public void setFollowSuperClass(boolean followSuperClass) { + this.followSuperClass = followSuperClass; + } + + private java.lang.Object __equalsCalc = null; + public synchronized boolean equals(java.lang.Object obj) { + if (!(obj instanceof ClassPredicate)) return false; + ClassPredicate other = (ClassPredicate) obj; + if (obj == null) return false; + if (this == obj) return true; + if (__equalsCalc != null) { + return (__equalsCalc == obj); + } + __equalsCalc = obj; + boolean _equals; + _equals = true && + ((this.names==null && other.getNames()==null) || + (this.names!=null && + java.util.Arrays.equals(this.names, other.getNames()))) && + this.followSubClass == other.isFollowSubClass() && + this.followSuperClass == other.isFollowSuperClass(); + __equalsCalc = null; + return _equals; + } + + private boolean __hashCodeCalc = false; + public synchronized int hashCode() { + if (__hashCodeCalc) { + return 0; + } + __hashCodeCalc = true; + int _hashCode = 1; + if (getNames() != null) { + for (int i=0; + i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/java/org/alfresco/repo/webservice/Utils.java b/source/java/org/alfresco/repo/webservice/Utils.java index 747936ba1f..3a36237fd1 100644 --- a/source/java/org/alfresco/repo/webservice/Utils.java +++ b/source/java/org/alfresco/repo/webservice/Utils.java @@ -615,25 +615,7 @@ public class Utils int pos = 0; for (org.alfresco.service.cmr.dictionary.PropertyDefinition ddPropDef : props.values()) { - PropertyDefinition propDef = new PropertyDefinition(); - propDef.setName(ddPropDef.getName().toString()); - propDef.setDataType(ddPropDef.getDataType().getName().toString()); - propDef.setMandatory(ddPropDef.isMandatory()); - propDef.setReadOnly(ddPropDef.isProtected()); - if (ddPropDef.getDefaultValue() != null) - { - propDef.setDefaultValue(ddPropDef.getDefaultValue()); - } - if (ddPropDef.getTitle() != null) - { - propDef.setTitle(ddPropDef.getTitle()); - } - if (ddPropDef.getDescription() != null) - { - propDef.setDescription(ddPropDef.getDescription()); - } - - // add it to the array + PropertyDefinition propDef = setupPropertyDefObject(ddPropDef); propDefs[pos] = propDef; pos++; } @@ -642,8 +624,6 @@ public class Utils classDef.setProperties(propDefs); } - // TODO need to get the child associations as well !! - // represent the associations Map assocs = ddClassDef.getAssociations(); if (assocs != null) @@ -652,35 +632,7 @@ public class Utils int pos = 0; for (org.alfresco.service.cmr.dictionary.AssociationDefinition ddAssocDef : assocs.values()) { - AssociationDefinition assocDef = new AssociationDefinition(); - assocDef.setName(ddAssocDef.getName().toString()); - assocDef.setIsChild(ddAssocDef.isChild()); - if (ddAssocDef.getTitle() != null) - { - assocDef.setTitle(ddAssocDef.getTitle()); - } - if (ddAssocDef.getDescription() != null) - { - assocDef.setDescription(ddAssocDef.getDescription()); - } - - RoleDefinition sourceRole = new RoleDefinition(); - if (ddAssocDef.getSourceRoleName() != null) - { - sourceRole.setName(ddAssocDef.getSourceRoleName().toString()); - } - sourceRole.setCardinality(setupSourceCardinalityObject(ddAssocDef)); - assocDef.setSourceRole(sourceRole); - - RoleDefinition targetRole = new RoleDefinition(); - if (ddAssocDef.getTargetRoleName() != null) - { - targetRole.setName(ddAssocDef.getTargetRoleName().toString()); - } - targetRole.setCardinality(setupTargetCardinalityObject(ddAssocDef));; - assocDef.setTargetRole(targetRole); - assocDef.setTargetClass(ddAssocDef.getTargetClass().getName().toString()); - + AssociationDefinition assocDef = setupAssociationDefObject(ddAssocDef); assocDefs[pos] = assocDef; pos++; } @@ -691,6 +643,76 @@ public class Utils return classDef; } + /** + * Creates a PropertyDefinition web service type object for the given + * repository PropertyDefinition + * + * @param ddPropertyDef The repository PropertyDefinition to generate + * @return The web service PropertyDefinition representation + */ + public static PropertyDefinition setupPropertyDefObject(org.alfresco.service.cmr.dictionary.PropertyDefinition ddPropDef) + { + PropertyDefinition propDef = new PropertyDefinition(); + propDef.setName(ddPropDef.getName().toString()); + propDef.setDataType(ddPropDef.getDataType().getName().toString()); + propDef.setMandatory(ddPropDef.isMandatory()); + propDef.setReadOnly(ddPropDef.isProtected()); + if (ddPropDef.getDefaultValue() != null) + { + propDef.setDefaultValue(ddPropDef.getDefaultValue()); + } + if (ddPropDef.getTitle() != null) + { + propDef.setTitle(ddPropDef.getTitle()); + } + if (ddPropDef.getDescription() != null) + { + propDef.setDescription(ddPropDef.getDescription()); + } + return propDef; + } + + /** + * Creates an AssociationDefinition web service type object for the given + * repository AssociationDefinition + * + * @param ddAssociationDef The repository AssociationDefinition to generate + * @return The web service AssociationDefinition representation + */ + public static AssociationDefinition setupAssociationDefObject(org.alfresco.service.cmr.dictionary.AssociationDefinition ddAssocDef) + { + AssociationDefinition assocDef = new AssociationDefinition(); + assocDef.setName(ddAssocDef.getName().toString()); + assocDef.setIsChild(ddAssocDef.isChild()); + if (ddAssocDef.getTitle() != null) + { + assocDef.setTitle(ddAssocDef.getTitle()); + } + if (ddAssocDef.getDescription() != null) + { + assocDef.setDescription(ddAssocDef.getDescription()); + } + + RoleDefinition sourceRole = new RoleDefinition(); + if (ddAssocDef.getSourceRoleName() != null) + { + sourceRole.setName(ddAssocDef.getSourceRoleName().toString()); + } + sourceRole.setCardinality(setupSourceCardinalityObject(ddAssocDef)); + assocDef.setSourceRole(sourceRole); + + RoleDefinition targetRole = new RoleDefinition(); + if (ddAssocDef.getTargetRoleName() != null) + { + targetRole.setName(ddAssocDef.getTargetRoleName().toString()); + } + targetRole.setCardinality(setupTargetCardinalityObject(ddAssocDef));; + assocDef.setTargetRole(targetRole); + assocDef.setTargetClass(ddAssocDef.getTargetClass().getName().toString()); + + return assocDef; + } + /** * Creates a web service Cardinality type for the source from the given repository AssociationDefinition * diff --git a/source/java/org/alfresco/repo/webservice/dictionary/DictionaryWebService.java b/source/java/org/alfresco/repo/webservice/dictionary/DictionaryWebService.java new file mode 100644 index 0000000000..c7219c9fdf --- /dev/null +++ b/source/java/org/alfresco/repo/webservice/dictionary/DictionaryWebService.java @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.webservice.dictionary; + +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.webservice.AbstractWebService; +import org.alfresco.repo.webservice.Utils; +import org.alfresco.repo.webservice.dictionary.ClassPredicate; +import org.alfresco.repo.webservice.dictionary.DictionaryFault; +import org.alfresco.repo.webservice.dictionary.DictionaryServiceSoapPort; +import org.alfresco.repo.webservice.types.AssociationDefinition; +import org.alfresco.repo.webservice.types.ClassDefinition; +import org.alfresco.repo.webservice.types.PropertyDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryException; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.dictionary.InvalidClassException; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Web service implementation of the DictionaryService. The WSDL for this + * service can be accessed from + * http://localhost:8080/alfresco/wsdl/dictionary-service.wsdl + * + * @author davidc + */ +public class DictionaryWebService extends AbstractWebService implements DictionaryServiceSoapPort +{ + private static Log logger = LogFactory.getLog(DictionaryWebService.class); + + // dependencies + private DictionaryService dictionaryService; + private NamespaceService namespaceService; + + + /** + * Sets the instance of the DictionaryService to be used + * + * @param dictionaryService The DictionaryService + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * Sets the instance of the NamespaceService to be used + */ + public void setNamespaceService(NamespaceService namespaceService) + { + this.namespaceService = namespaceService; + } + + + /* + * (non-Javadoc) + * @see org.alfresco.repo.webservice.dictionary.DictionaryServiceSoapPort#getClasses(org.alfresco.repo.webservice.dictionary.ClassPredicate[], org.alfresco.repo.webservice.dictionary.ClassPredicate[]) + */ + public ClassDefinition[] getClasses(ClassPredicate types, ClassPredicate aspects) throws RemoteException, DictionaryFault + { + try + { + Set classDefs = new HashSet(); + classDefs.addAll(getClassDefs(types, false)); + classDefs.addAll(getClassDefs(aspects, true)); + + List wsClassDefs = new ArrayList(classDefs.size()); + for (org.alfresco.service.cmr.dictionary.ClassDefinition classDef : classDefs) + { + wsClassDefs.add(Utils.setupClassDefObject(classDef)); + } + + return wsClassDefs.toArray(new ClassDefinition[wsClassDefs.size()]); + } + catch (Throwable e) + { + if (logger.isDebugEnabled()) + { + logger.error("Unexpected error occurred", e); + } + throw new DictionaryFault(0, e.getMessage()); + } + } + + + /* + * (non-Javadoc) + * @see org.alfresco.repo.webservice.dictionary.DictionaryServiceSoapPort#getProperties(java.lang.String[]) + */ + public PropertyDefinition[] getProperties(String[] propertyNames) throws RemoteException, DictionaryFault + { + try + { + PropertyDefinition[] propDefs = new PropertyDefinition[propertyNames.length]; + + int i = 0; + for (String propertyName : propertyNames) + { + QName propertyQName = QName.createQName(propertyName, namespaceService); + org.alfresco.service.cmr.dictionary.PropertyDefinition ddPropDef = dictionaryService.getProperty(propertyQName); + if (ddPropDef == null) + { + throw new AlfrescoRuntimeException("Property propertyName does not exist."); + } + propDefs[i++] = Utils.setupPropertyDefObject(ddPropDef); + } + + return propDefs; + } + catch (Throwable e) + { + if (logger.isDebugEnabled()) + { + logger.error("Unexpected error occurred", e); + } + throw new DictionaryFault(0, e.getMessage()); + } + } + + + /* + * (non-Javadoc) + * @see org.alfresco.repo.webservice.dictionary.DictionaryServiceSoapPort#getAssociations(java.lang.String[]) + */ + public AssociationDefinition[] getAssociations(String[] associationNames) throws RemoteException, DictionaryFault + { + try + { + AssociationDefinition[] assocDefs = new AssociationDefinition[associationNames.length]; + + int i = 0; + for (String associationName : associationNames) + { + QName associationQName = QName.createQName(associationName, namespaceService); + org.alfresco.service.cmr.dictionary.AssociationDefinition ddAssocDef = dictionaryService.getAssociation(associationQName); + if (ddAssocDef == null) + { + throw new AlfrescoRuntimeException("Property propertyName does not exist."); + } + assocDefs[i++] = Utils.setupAssociationDefObject(ddAssocDef); + } + + return assocDefs; + } + catch (Throwable e) + { + if (logger.isDebugEnabled()) + { + logger.error("Unexpected error occurred", e); + } + throw new DictionaryFault(0, e.getMessage()); + } + } + + + /* + * (non-Javadoc) + * @see org.alfresco.repo.webservice.dictionary.DictionaryServiceSoapPort#isSubClass(java.lang.String, java.lang.String) + */ + public boolean isSubClass(String className, String isSubClassOfName) throws RemoteException, DictionaryFault + { + try + { + QName classQName = QName.createQName(className, namespaceService); + QName isSubClassOfQName = QName.createQName(isSubClassOfName, namespaceService); + return dictionaryService.isSubClass(classQName, isSubClassOfQName); + } + catch (Throwable e) + { + if (logger.isDebugEnabled()) + { + logger.error("Unexpected error occurred", e); + } + throw new DictionaryFault(0, e.getMessage()); + } + } + + + /** + * Retrieve class definitions that match the provided class predicate + * + * @param predicate the class predicate to filter by + * @param forAspects futher filtering on type or aspect + * @return class definitions that match + */ + private Set getClassDefs(ClassPredicate predicate, boolean forAspects) + { + Set classDefs = new HashSet(); + if (predicate != null) + { + String[] predicateTypeNames = predicate.getNames(); + if (predicateTypeNames != null) + { + // predicate class names have been provided, therefore retrieve class definitions for those + for (String predicateTypeName : predicateTypeNames) + { + QName classQName = QName.createQName(predicateTypeName, namespaceService); + org.alfresco.service.cmr.dictionary.ClassDefinition classDef = dictionaryService.getClass(classQName); + if (classDef == null || classDef.isAspect() != forAspects) + { + throw new InvalidClassException(classQName); + } + classDefs.add(classDef); + } + + // also retrieve sub-classes and super-classes as specified by predicate + if (predicate.isFollowSuperClass() || predicate.isFollowSubClass()) + { + Set touchedClassDefs = new HashSet(); + for (org.alfresco.service.cmr.dictionary.ClassDefinition classDef : classDefs) + { + if (predicate.isFollowSuperClass()) + { + getSuperClasses(classDef, touchedClassDefs, true); + } + else if (predicate.isFollowSubClass()) + { + getSubClasses(classDef, touchedClassDefs, true); + } + } + classDefs.addAll(touchedClassDefs); + } + } + } + else + { + // return all classes + Collection classQNames = (forAspects) ? dictionaryService.getAllAspects() : dictionaryService.getAllTypes(); + for (QName classQName : classQNames) + { + classDefs.add(dictionaryService.getClass(classQName)); + } + } + + return classDefs; + } + + + /** + * Retrieve the super-class of the specified class + * + * @param classDef the class definition to retrieve super-classes for + * @param superClasses the collection to place super-classes into + * @param recurse true => recurse down the sub-class hierarchy + */ + private void getSuperClasses(org.alfresco.service.cmr.dictionary.ClassDefinition classDef, Set superClasses, boolean recurse) + { + QName superClass = classDef.getParentName(); + if (superClass != null) + { + org.alfresco.service.cmr.dictionary.ClassDefinition superClassDef = dictionaryService.getClass(superClass); + superClasses.add(superClassDef); + if (recurse) + { + getSuperClasses(superClassDef, superClasses, recurse); + } + } + } + + + /** + * Retrieve the sub-class of the specified class + * + * @param classDef the class definition to retrieve sub-classes for + * @param superClasses the collection to place sub-classes into + * @param recurse true => recurse up the super-class hierarchy + */ + private void getSubClasses(org.alfresco.service.cmr.dictionary.ClassDefinition classDef, Set subClasses, boolean recurse) + { + QName superClass = classDef.getName(); + Collection candidates = (classDef.isAspect()) ? dictionaryService.getAllAspects() : dictionaryService.getAllTypes(); + + // Note: this is the brute force way of finding sub-classes + // TODO: Add support into Dictionary for retrieving sub-classes + for (QName candidate : candidates) + { + if (dictionaryService.isSubClass(candidate, superClass) && !candidate.equals(superClass)) + { + org.alfresco.service.cmr.dictionary.ClassDefinition subClassDef = dictionaryService.getClass(candidate); + subClasses.add(subClassDef); + if (recurse) + { + getSubClasses(subClassDef, subClasses, recurse); + } + } + } + } + +} diff --git a/source/java/web-services-application-context.xml b/source/java/web-services-application-context.xml index bd826b1e6e..e3ac65b950 100644 --- a/source/java/web-services-application-context.xml +++ b/source/java/web-services-application-context.xml @@ -83,6 +83,15 @@ + + + + + + + + + diff --git a/source/web/WEB-INF/server-config.wsdd b/source/web/WEB-INF/server-config.wsdd index ebaa17f4bf..982c5abe8c 100644 --- a/source/web/WEB-INF/server-config.wsdd +++ b/source/web/WEB-INF/server-config.wsdd @@ -3035,6 +3035,303 @@ /> + + Dictionary web service API. + /wsdl/dictionary-service.wsdl + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/wsdl/dictionary-service.wsdl b/source/wsdl/dictionary-service.wsdl new file mode 100644 index 0000000000..e6a5513c00 --- /dev/null +++ b/source/wsdl/dictionary-service.wsdl @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Retrieves the class definitions of types and aspects. + + + + + + Retrieves property definitions. + + + + + + Retrieves association definitions. + + + + + + Determines whether a type (or aspect) is a sub class of another type (or aspect). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Provides read access to the Repository Dictionary. + + + + + + diff --git a/source/wsdl/types.xsd b/source/wsdl/types.xsd index 5eb4d416a5..2fb45f84c5 100644 --- a/source/wsdl/types.xsd +++ b/source/wsdl/types.xsd @@ -210,7 +210,7 @@ - +