Author: tmortagne
Date: 2008-01-18 19:01:53 +0100 (Fri, 18 Jan 2008)
New Revision: 6960

Modified:
   
xwiki-platform/xwiki-plugins/trunk/application-manager/src/main/java/com/xpn/xwiki/plugin/applicationmanager/doc/XWikiApplication.java
Log:
XAAM-47: XWikiApplication.getDocsToInclude and XWikiApplication.getDocsToLink 
return too many documents.
Also improved the way it recurse in dependencies applications as it now 
executes just one hql query to resolve all documents names in place of one by 
application.

Modified: 
xwiki-platform/xwiki-plugins/trunk/application-manager/src/main/java/com/xpn/xwiki/plugin/applicationmanager/doc/XWikiApplication.java
===================================================================
--- 
xwiki-platform/xwiki-plugins/trunk/application-manager/src/main/java/com/xpn/xwiki/plugin/applicationmanager/doc/XWikiApplication.java
      2008-01-18 17:20:13 UTC (rev 6959)
+++ 
xwiki-platform/xwiki-plugins/trunk/application-manager/src/main/java/com/xpn/xwiki/plugin/applicationmanager/doc/XWikiApplication.java
      2008-01-18 18:01:53 UTC (rev 6960)
@@ -20,7 +20,9 @@
 
 package com.xpn.xwiki.plugin.applicationmanager.doc;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -47,6 +49,31 @@
     private static final Pattern EXT_DOCNAME_PATTERN = 
Pattern.compile("^\\[(.*)\\]$");
 
     /**
+     * HQL where key word.
+     */
+    private static final String HQL_WHERE = "where";
+
+    /**
+     * HQL or key word.
+     */
+    private static final String HQL_OR = " or ";
+
+    /**
+     * HQL and key word.
+     */
+    private static final String HQL_AND = " and ";
+
+    /**
+     * Filter to add in a named HQL query for a specific document.
+     */
+    private static final String HQL_FILTER_DOC_EQUALS = "doc.fullName = ?";
+
+    /**
+     * Filter to add in a named HQL query to filter documents with a pattern.
+     */
+    private static final String HQL_FILTER_DOC_PATTERN = "doc.fullName like ?";
+
+    /**
      * Create new XWikiApplication managing provided XWikiDocument.
      * 
      * @param xdoc the encapsulated XWikiDocument
@@ -401,101 +428,145 @@
     }
 
     /**
-     * Insert in <code>docsNames</code> all documents names 
<code>docsNamesToResolve</code>
-     * contains.
-     * <p>
-     * For each of these documents names, if are between "[" and "]", are 
considered as SQL matching
-     * string to use with "like".
+     * Create a HQL where clause containing applications documents filter for 
provided documents
+     * type.
      * 
-     * @param docsNames the collection to complete with resolved documents 
names.
-     * @param docsNamesToResolve the documents names to resolve.
-     * @param context the XWiki context.
-     * @throws XWikiException error when resolving SQL matching.
-     * @see #EXT_DOCNAME_PATTERN
-     * @see 
com.xpn.xwiki.store.XWikiStoreInterface#searchDocumentsNames(String, 
XWikiContext)
+     * @param applications the applications from which to get filters.
+     * @param type the XWikiApplicationClass field where to find documents 
names list :
+     *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCUMENTS},
+     *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCSTOINCLUDE},
+     *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCSTOLINK}.
+     * @param values the HQL values list filled for the named query.
+     * @param includeAppDesc if true application descriptor document names are 
included in the
+     *            generated filter.
+     * @return a HQL where clause containing applications documents filter for 
provided documents
+     *         type.
+     * @throws XWikiException error when creating HQL filter.
      */
-    private static void resolveDocumentsNames(Collection docsNames,
-        Collection docsNamesToResolve, XWikiContext context) throws 
XWikiException
+    private static String createApplicationsHqlFilter(Collection applications, 
String type,
+        Collection values, boolean includeAppDesc) throws XWikiException
     {
-        Matcher matcher;
+        StringBuffer filter = new StringBuffer();
 
-        StringBuffer where = new StringBuffer();
-        for (Iterator it = docsNamesToResolve.iterator(); it.hasNext();) {
-            String docName = (String) it.next();
+        for (Iterator it = applications.iterator(); it.hasNext();) {
+            if (filter.length() > 0) {
+                filter.append(HQL_OR);
+            }
 
-            matcher = EXT_DOCNAME_PATTERN.matcher(docName);
-            if (matcher.matches()) {
-                if (where.length() > 0) {
-                    where.append(" or ");
-                }
-                where.append("doc.fullName like 
'").append(matcher.group(1)).append("'");
-            } else {
-                docsNames.add(docName);
+            XWikiApplication app = (XWikiApplication) it.next();
+
+            String appFilter = app.createHqlFilter(type, values, false, 
includeAppDesc);
+
+            if (!appFilter.isEmpty()) {
+                filter.append("(");
+                filter.append(appFilter);
+                filter.append(")");
             }
         }
 
-        if (where.length() > 0) {
-            
docsNames.addAll(context.getWiki().getStore().searchDocumentsNames("where " + 
where,
-                context));
-        }
+        return filter.toString();
     }
 
     /**
-     * Insert in <code>docsNames</code> all documents names of type 
<code>type</code>
-     * application contains.
-     * <p>
-     * For each of these documents names, if are between "[" and "]", are 
considered as SQL matching
-     * string to use with "like".
+     * Create a HQL where clause containing application documents filter for 
provided documents
+     * type.
      * 
-     * @param docsNames the collection to complete with resolved documents 
names.
      * @param type the XWikiApplicationClass field where to find documents 
names list :
      *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCUMENTS},
      *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCSTOINCLUDE},
      *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCSTOLINK}.
-     * @param includeAppDesc if true application descriptor document names is 
add to
-     *            <code>docsNames</code>.
-     * @throws XWikiException error when resolving SQL matching.
-     * @see XWikiApplicationClass#FIELD_DOCUMENTS
-     * @see XWikiApplicationClass#FIELD_DOCSTOINCLUDE
-     * @see XWikiApplicationClass#FIELD_DOCSTOLINK
-     * @see #resolveDocumentsNames(Collection, Collection, XWikiContext)
+     * @param values the HQL values list filled for the named query.
+     * @param recurse indicate if dependencies applications filters are 
included in the generated
+     *            filter.
+     * @param includeAppDesc if true application descriptor document names are 
included in the
+     *            generated filter.
+     * @return a HQL where clause containing application documents filter for 
provided documents
+     *         type.
+     * @throws XWikiException error when creating HQL filter.
      */
-    private void resolveDocumentsNames(Collection docsNames, String type, 
boolean includeAppDesc)
-        throws XWikiException
+    private String createHqlFilter(String type, Collection values, boolean 
recurse,
+        boolean includeAppDesc) throws XWikiException
     {
-        if (includeAppDesc) {
-            docsNames.add(getFullName());
+        StringBuffer filter = new StringBuffer();
+
+        List patterns = getListValue(type);
+
+        if (!patterns.isEmpty()) {
+            // Filter with applications documents
+            if (!type.equals(XWikiApplicationClass.FIELD_DOCUMENTS)) {
+                filter.append(createHqlFilter(getDocuments(), values, false));
+            }
+
+            // Filter with provided applications documents type
+            String typeFilter = createHqlFilter(getListValue(type), values, 
includeAppDesc);
+
+            if (!typeFilter.isEmpty()) {
+                if (filter.length() > 0) {
+                    filter.append(HQL_AND);
+                }
+
+                filter.append(typeFilter);
+            }
         }
 
-        resolveDocumentsNames(docsNames, getListValue(type), context);
+        // Add dependencies applications hql filters for provided type
+        if (recurse) {
+            Collection applications = getXWikiApplicationSet(true, context);
+
+            String dependenciesFilter =
+                createApplicationsHqlFilter(applications, type, values, 
includeAppDesc);
+
+            if (!dependenciesFilter.isEmpty()) {
+                if (filter.length() > 0) {
+                    filter.append(HQL_OR);
+                }
+                filter.append(dependenciesFilter);
+            }
+        }
+
+        return filter.toString();
     }
 
     /**
-     * Insert in <code>docsNames</code> all documents names of type
-     * <code>type</code> <code>applications</code> XWikiApplication list 
contains.
-     * <p>
-     * For each of these documents names, if are between "[" and "]", are 
considered as SQL matching
-     * string to use with "like".
+     * Convert provided filter list in one hql where clause.
      * 
-     * @param docsNames the collection to complete with resolved documents 
names.
-     * @param applications the applications containing documents names to 
resolve and add to
-     *            <code>docsNames</code>.
-     * @param type the XWikiApplicationClass field where to find documents 
names list :
-     *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCUMENTS},
-     *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCSTOINCLUDE},
-     *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCSTOLINK}.
-     * @param includeAppDesc if true application descriptor document names is 
add to
-     *            <code>docsNames</code>.
-     * @throws XWikiException error when resolving SQL matching.
+     * @param docsNamesToResolve the application filters.
+     * @param values the HQL values list filled for the named query.
+     * @param includeAppDesc if true application descriptor document names are 
included in the
+     *            generated filter.
+     * @return a HQL where clause containing application documents filter for 
provided documents
+     *         type.
      */
-    private static void resolveApplicationsDocsNames(Collection docsNames,
-        Collection applications, String type, boolean includeAppDesc) throws 
XWikiException
+    private String createHqlFilter(Collection docsNamesToResolve, Collection 
values,
+        boolean includeAppDesc)
     {
-        for (Iterator it = applications.iterator(); it.hasNext();) {
-            XWikiApplication app = (XWikiApplication) it.next();
+        StringBuffer filter = new StringBuffer();
 
-            app.resolveDocumentsNames(docsNames, type, includeAppDesc);
+        if (includeAppDesc) {
+            filter.append(HQL_FILTER_DOC_EQUALS);
+            values.add(this.getFullName());
         }
+
+        for (Iterator it = docsNamesToResolve.iterator(); it.hasNext();) {
+            if (filter.length() > 0) {
+                filter.append(HQL_OR);
+            }
+
+            String docName = (String) it.next();
+
+            Matcher matcher = EXT_DOCNAME_PATTERN.matcher(docName);
+            if (matcher.matches()) {
+                // Add a pattern
+                filter.append(HQL_FILTER_DOC_PATTERN);
+                values.add(matcher.group(1));
+            } else {
+                // Add a document name
+                filter.append(HQL_FILTER_DOC_EQUALS);
+                values.add(docName);
+            }
+        }
+
+        return filter.toString();
     }
 
     /**
@@ -504,14 +575,14 @@
      * For each of these documents names, if are between "[" and "]", are 
considered as SQL matching
      * string to use with "like".
      * 
-     * @param type the XWikiApplicationClass field where to find documents 
names list :
+     * @param type type the XWikiApplicationClass field where to find 
documents names list :
      *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCUMENTS},
      *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCSTOINCLUDE},
      *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCSTOLINK}.
      * @param recurse if true it follow recursively all applications 
dependencies, if false parse
      *            only direct dependencies.
-     * @param includeAppDesc if true application descriptor document names is 
add to
-     *            <code>docsNames</code>.
+     * @param includeAppDesc if true application descriptor document names is 
added to the returned
+     *            set.
      * @return all documents names of type <code>type</code> application 
contains.
      * @throws XWikiException error when:
      *             <ul>
@@ -520,19 +591,56 @@
      *             database.</li>
      *             </ul>
      */
-    private Set getDocsNameSet(String type, boolean recurse, boolean 
includeAppDesc)
+    private Set getDocsNamesByType(String type, boolean recurse, boolean 
includeAppDesc)
         throws XWikiException
     {
-        Set documents = new HashSet();
+        List values = new ArrayList();
 
-        resolveDocumentsNames(documents, type, includeAppDesc);
+        String where = createHqlFilter(type, values, recurse, includeAppDesc);
 
-        if (recurse) {
-            resolveApplicationsDocsNames(documents, 
getXWikiApplicationSet(true, context), type,
-                includeAppDesc);
+        return where.isEmpty() ? Collections.EMPTY_SET : new 
HashSet(context.getWiki().getStore()
+            .searchDocumentsNames(HQL_WHERE + " " + where, values, context));
+    }
+
+    /**
+     * Get and resolve all documents names of type <code>type</code> provided 
applications
+     * contains.
+     * <p>
+     * For each of these documents names, if are between "[" and "]", are 
considered as SQL matching
+     * string to use with "like".
+     * 
+     * @param applications the applications from which to get documents names.
+     * @param type type the XWikiApplicationClass field where to find 
documents names list :
+     *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCUMENTS},
+     *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCSTOINCLUDE},
+     *            [EMAIL PROTECTED] XWikiApplicationClass#FIELD_DOCSTOLINK}.
+     * @param includeAppDesc if true application descriptor document names is 
added to the returned
+     *            set.
+     * @return all documents names of type <code>type</code> provided 
applications contains.
+     * @throws XWikiException error when resolving SQL matching.
+     */
+    private static Set getApplicationsDocsNamesByType(Collection applications, 
String type,
+        boolean includeAppDesc) throws XWikiException
+    {
+        Set set = Collections.EMPTY_SET;
+        if (!applications.isEmpty()) {
+            List values = new ArrayList();
+
+            String where =
+                createApplicationsHqlFilter(applications, type, values, 
includeAppDesc);
+
+            XWikiApplication app = (XWikiApplication) 
applications.iterator().next();
+
+            if (where.isEmpty()) {
+                set = Collections.EMPTY_SET;
+            } else {
+                set =
+                    new 
HashSet(app.context.getWiki().getStore().searchDocumentsNames(
+                        HQL_WHERE + " " + where, values, app.context));
+            }
         }
 
-        return documents;
+        return set;
     }
 
     /**
@@ -543,7 +651,7 @@
      * 
      * @param recurse if true it follow recursively all applications 
dependencies, if false parse
      *            only direct dependencies.
-     * @param includeAppDesc if true application descriptor document names is 
add to
+     * @param includeAppDesc if true application descriptor document names is 
added to
      *            <code>docsNames</code>.
      * @return all documents names application contains.
      * @throws XWikiException error when:
@@ -557,7 +665,7 @@
      */
     public Set getDocumentsNames(boolean recurse, boolean includeAppDesc) 
throws XWikiException
     {
-        return getDocsNameSet(XWikiApplicationClass.FIELD_DOCUMENTS, recurse, 
includeAppDesc);
+        return getDocsNamesByType(XWikiApplicationClass.FIELD_DOCUMENTS, 
recurse, includeAppDesc);
     }
 
     /**
@@ -580,7 +688,7 @@
      */
     public Set getDocsNameToInclude(boolean recurse) throws XWikiException
     {
-        return getDocsNameSet(XWikiApplicationClass.FIELD_DOCSTOINCLUDE, 
recurse, false);
+        return getDocsNamesByType(XWikiApplicationClass.FIELD_DOCSTOINCLUDE, 
recurse, false);
     }
 
     /**
@@ -604,12 +712,8 @@
      */
     public static Set getDocsNameToInclude(Collection applications) throws 
XWikiException
     {
-        Set docsToInclude = new HashSet();
-
-        resolveApplicationsDocsNames(docsToInclude, applications,
+        return getApplicationsDocsNamesByType(applications,
             XWikiApplicationClass.FIELD_DOCSTOINCLUDE, false);
-
-        return docsToInclude;
     }
 
     /**
@@ -632,7 +736,7 @@
      */
     public Set getDocsNameToLink(boolean recurse) throws XWikiException
     {
-        return getDocsNameSet(XWikiApplicationClass.FIELD_DOCSTOLINK, recurse, 
false);
+        return getDocsNamesByType(XWikiApplicationClass.FIELD_DOCSTOLINK, 
recurse, false);
     }
 
     /**
@@ -656,11 +760,7 @@
      */
     public static Set getDocsNameToLink(Collection applications) throws 
XWikiException
     {
-        Set docsToLink = new HashSet();
-
-        resolveApplicationsDocsNames(docsToLink, applications,
+        return getApplicationsDocsNamesByType(applications,
             XWikiApplicationClass.FIELD_DOCSTOLINK, false);
-
-        return docsToLink;
     }
 }

_______________________________________________
notifications mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/notifications

Reply via email to