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/dictionary/DictionaryWebService.java b/source/java/org/alfresco/repo/webservice/dictionary/DictionaryWebService.java
new file mode 100644
index 0000000000..873ff1c2eb
--- /dev/null
+++ b/source/java/org/alfresco/repo/webservice/dictionary/DictionaryWebService.java
@@ -0,0 +1,215 @@
+/*
+ * 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.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.ClassDefinition;
+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());
+ }
+ }
+
+
+ /**
+ * 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..2256b93357 100644
--- a/source/web/WEB-INF/server-config.wsdd
+++ b/source/web/WEB-INF/server-config.wsdd
@@ -3035,6 +3035,326 @@
/>
+
+ 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..e53a34cbac
--- /dev/null
+++ b/source/wsdl/dictionary-service.wsdl
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Retrieves the class definitions of types and aspects.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Provides read access to the Repository Dictionary.
+
+
+
+
+
+