Search in sources :

Example 1 with SearchResult

use of org.xwiki.rest.model.jaxb.SearchResult in project xwiki-platform by xwiki.

the class BaseSearchResult method searchQuery.

/**
 * Search for query using xwql, hql, lucene. Limit the search only to Pages. Search for keyword
 *
 * @param query the query to be executed
 * @param queryTypeString can be "xwql", "hql" or "lucene".
 * @param orderField the field to be used to order the results.
 * @param order "asc" or "desc"
 * @param number number of results to be returned
 * @param start 0-based start offset.
 * @return a list of {@link SearchResult} objects containing the found items, or an empty list if the specified
 *         query type string doesn't represent a supported query type.
 */
protected List<SearchResult> searchQuery(String query, String queryTypeString, String wikiName, String wikis, boolean hasProgrammingRights, String orderField, String order, boolean distinct, int number, int start, Boolean withPrettyNames, String className) throws Exception {
    String currentWiki = Utils.getXWikiContext(componentManager).getWikiId();
    /* This try is just needed for executing the finally clause. */
    try {
        if (wikiName != null) {
            Utils.getXWikiContext(componentManager).setWikiId(wikiName);
        }
        List<SearchResult> result;
        if (queryTypeString != null) {
            SearchSource searchSource = this.componentManager.getInstance(SearchSource.class, queryTypeString.toLowerCase());
            result = searchSource.search(query, wikiName, wikis, hasProgrammingRights, orderField, order, distinct, number, start, withPrettyNames, className, uriInfo);
        } else {
            result = new ArrayList<SearchResult>();
        }
        return result;
    } finally {
        Utils.getXWikiContext(componentManager).setWikiId(currentWiki);
    }
}
Also used : SearchSource(org.xwiki.rest.internal.resources.search.SearchSource) SearchResult(org.xwiki.rest.model.jaxb.SearchResult)

Example 2 with SearchResult

use of org.xwiki.rest.model.jaxb.SearchResult in project xwiki-platform by xwiki.

the class BaseSearchResult method searchPages.

/**
 * Search for keyword in the given scopes. Limit the search only to Pages. Search for keyword
 *
 * @param keywords the string that will be used in a "like" XWQL clause.
 * @param number number of results to be returned.
 * @param start 0-based start offset.
 * @param orderField the field to be used to order the results.
 * @param order "asc" or "desc"
 * @return the results.
 */
protected List<SearchResult> searchPages(List<SearchScope> searchScopes, String keywords, String wikiName, String space, boolean hasProgrammingRights, int number, int start, String orderField, String order, Boolean withPrettyNames) throws QueryException, IllegalArgumentException, UriBuilderException, XWikiException {
    XWiki xwikiApi = Utils.getXWikiApi(componentManager);
    String database = Utils.getXWikiContext(componentManager).getWikiId();
    /* This try is just needed for executing the finally clause. */
    try {
        List<SearchResult> result = new ArrayList<SearchResult>();
        if (keywords == null) {
            return result;
        }
        Formatter f = new Formatter();
        /*
             * If the order field is already one of the field hard coded in the base query, then do not add it to the
             * select clause.
             */
        String addColumn = "";
        if (!StringUtils.isBlank(orderField)) {
            addColumn = (orderField.equals("") || orderField.equals("fullName") || orderField.equals("name") || orderField.equals("space")) ? "" : ", doc." + orderField;
        }
        if (space != null) {
            f.format("select distinct doc.fullName, doc.space, doc.name, doc.language");
            f.format(addColumn);
            f.format(" from XWikiDocument as doc where doc.space = :space and ( ");
        } else {
            f.format("select distinct doc.fullName, doc.space, doc.name, doc.language");
            f.format(addColumn);
            f.format(" from XWikiDocument as doc where ( ");
        }
        /* Look for scopes related to pages */
        int acceptedScopes = 0;
        for (int i = 0; i < searchScopes.size(); i++) {
            SearchScope scope = searchScopes.get(i);
            switch(scope) {
                case CONTENT:
                    f.format("upper(doc.content) like :keywords ");
                    acceptedScopes++;
                    break;
                case NAME:
                    f.format("upper(doc.fullName) like :keywords ");
                    acceptedScopes++;
                    break;
                case TITLE:
                    f.format("upper(doc.title) like :keywords ");
                    acceptedScopes++;
                    break;
            }
            if (i != searchScopes.size() - 1) {
                f.format(" or ");
            }
        }
        /* If we don't find any scope related to pages then return empty results */
        if (acceptedScopes == 0) {
            return result;
        }
        /* Build the order clause. */
        String orderClause = null;
        if (StringUtils.isBlank(orderField)) {
            orderClause = "doc.fullName asc";
        } else {
            /* Check if the order parameter is a valid "asc" or "desc" string, otherwise use "asc" */
            if ("asc".equals(order) || "desc".equals(order)) {
                orderClause = String.format("doc.%s %s", orderField, order);
            } else {
                orderClause = String.format("doc.%s asc", orderField);
            }
        }
        // Add ordering
        f.format(") order by %s", orderClause);
        String query = f.toString();
        List<Object> queryResult = null;
        /* This is needed because if the :space placeholder is not in the query, setting it would cause an exception */
        if (space != null) {
            queryResult = this.queryManager.createQuery(query, Query.XWQL).bindValue("keywords", String.format("%%%s%%", keywords.toUpperCase())).bindValue("space", space).addFilter(Utils.getHiddenQueryFilter(this.componentManager)).setOffset(start).setLimit(number).execute();
        } else {
            queryResult = this.queryManager.createQuery(query, Query.XWQL).bindValue("keywords", String.format("%%%s%%", keywords.toUpperCase())).addFilter(Utils.getHiddenQueryFilter(this.componentManager)).setOffset(start).setLimit(number).execute();
        }
        for (Object object : queryResult) {
            Object[] fields = (Object[]) object;
            String spaceId = (String) fields[1];
            List<String> spaces = Utils.getSpacesFromSpaceId(spaceId);
            String pageName = (String) fields[2];
            String language = (String) fields[3];
            String pageId = Utils.getPageId(wikiName, spaces, pageName);
            String pageFullName = Utils.getPageFullName(wikiName, spaces, pageName);
            /* Check if the user has the right to see the found document */
            if (xwikiApi.hasAccessLevel("view", pageId)) {
                Document doc = xwikiApi.getDocument(pageFullName);
                String title = doc.getDisplayTitle();
                SearchResult searchResult = objectFactory.createSearchResult();
                searchResult.setType("page");
                searchResult.setId(pageId);
                searchResult.setPageFullName(pageFullName);
                searchResult.setTitle(title);
                searchResult.setWiki(wikiName);
                searchResult.setSpace(spaceId);
                searchResult.setPageName(pageName);
                searchResult.setVersion(doc.getVersion());
                searchResult.setAuthor(doc.getAuthor());
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(doc.getDate());
                searchResult.setModified(calendar);
                if (withPrettyNames) {
                    searchResult.setAuthorName(Utils.getAuthorName(doc.getAuthorReference(), componentManager));
                }
                String pageUri = null;
                if (StringUtils.isBlank(language)) {
                    pageUri = Utils.createURI(this.uriInfo.getBaseUri(), PageResource.class, wikiName, spaces, pageName).toString();
                } else {
                    searchResult.setLanguage(language);
                    pageUri = Utils.createURI(this.uriInfo.getBaseUri(), PageTranslationResource.class, wikiName, spaces, pageName, language).toString();
                }
                Link pageLink = new Link();
                pageLink.setHref(pageUri);
                pageLink.setRel(Relations.PAGE);
                searchResult.getLinks().add(pageLink);
                result.add(searchResult);
            }
        }
        return result;
    } finally {
        Utils.getXWikiContext(componentManager).setWikiId(database);
    }
}
Also used : Formatter(java.util.Formatter) Calendar(java.util.Calendar) ArrayList(java.util.ArrayList) XWiki(com.xpn.xwiki.api.XWiki) SearchResult(org.xwiki.rest.model.jaxb.SearchResult) Document(com.xpn.xwiki.api.Document) Link(org.xwiki.rest.model.jaxb.Link)

Example 3 with SearchResult

use of org.xwiki.rest.model.jaxb.SearchResult in project xwiki-platform by xwiki.

the class BaseSearchResult method searchSpaces.

/**
 * Search for keyword in the given scopes. Limit the search only to spaces.
 *
 * @param keywords the string that will be used in a "like" XWQL clause
 * @param number number of results to be returned
 * @param start 0-based start offset
 * @return the results.
 */
protected List<SearchResult> searchSpaces(String keywords, String wikiName, int number, int start) throws QueryException, IllegalArgumentException, UriBuilderException, XWikiException {
    List<SearchResult> result = new ArrayList<SearchResult>();
    if (StringUtils.isEmpty(keywords)) {
        return result;
    }
    String escapedKeywords = keywords.replaceAll("([%_!])", "!$1");
    String query = "select space.reference from XWikiSpace as space" + " where lower(space.name) like lower(:keywords) escape '!'" + " or lower(space.reference) like lower(:prefix) escape '!'" + " order by lower(space.reference), space.reference";
    List<Object> queryResult = queryManager.createQuery(query, Query.HQL).bindValue("keywords", String.format("%%%s%%", escapedKeywords)).bindValue("prefix", String.format("%s%%", escapedKeywords)).setWiki(wikiName).setLimit(number).setOffset(start).addFilter(this.hiddenSpaceFilter).execute();
    XWiki xwikiApi = Utils.getXWikiApi(componentManager);
    for (Object object : queryResult) {
        String spaceId = (String) object;
        List<String> spaces = Utils.getSpacesFromSpaceId(spaceId);
        SpaceReference spaceReference = new SpaceReference(wikiName, spaces);
        if (this.authorizationManager.hasAccess(Right.VIEW, spaceReference)) {
            Document spaceDoc = xwikiApi.getDocument(spaceReference);
            SearchResult searchResult = objectFactory.createSearchResult();
            searchResult.setType("space");
            searchResult.setId(spaceId);
            searchResult.setWiki(wikiName);
            searchResult.setSpace(spaceId);
            searchResult.setTitle(spaceDoc != null ? spaceDoc.getPlainTitle() : spaceReference.getName());
            // Add a link to the space information.
            Link spaceLink = new Link();
            spaceLink.setRel(Relations.SPACE);
            spaceLink.setHref(Utils.createURI(uriInfo.getBaseUri(), SpaceResource.class, wikiName, spaces).toString());
            searchResult.getLinks().add(spaceLink);
            // Add a link to the home page if it exists and it is viewable.
            if (spaceDoc != null && !spaceDoc.isNew()) {
                Link pageLink = new Link();
                pageLink.setHref(Utils.createURI(uriInfo.getBaseUri(), PageResource.class, wikiName, spaces, spaceDoc.getName()).toString());
                pageLink.setRel(Relations.HOME);
                searchResult.getLinks().add(pageLink);
            }
            result.add(searchResult);
        }
    }
    return result;
}
Also used : SpaceReference(org.xwiki.model.reference.SpaceReference) ArrayList(java.util.ArrayList) XWiki(com.xpn.xwiki.api.XWiki) SearchResult(org.xwiki.rest.model.jaxb.SearchResult) Document(com.xpn.xwiki.api.Document) Link(org.xwiki.rest.model.jaxb.Link)

Example 4 with SearchResult

use of org.xwiki.rest.model.jaxb.SearchResult in project xwiki-platform by xwiki.

the class BaseSearchResult method searchObjects.

/**
 * Search for keyword in the given scopes. Limit the search only to Objects.
 *
 * @param number number of results to be returned
 * @param start 0-based start offset
 * @param orderField the field to be used to order the results
 * @param order "asc" or "desc"
 * @return the results
 */
protected List<SearchResult> searchObjects(String keywords, String wikiName, String space, boolean hasProgrammingRights, int number, int start, String orderField, String order, Boolean withPrettyNames) throws QueryException, IllegalArgumentException, UriBuilderException, XWikiException {
    XWikiContext xwikiContext = Utils.getXWikiContext(componentManager);
    XWiki xwikiApi = Utils.getXWikiApi(componentManager);
    String database = Utils.getXWikiContext(componentManager).getWikiId();
    /* This try is just needed for executing the finally clause. */
    try {
        List<SearchResult> result = new ArrayList<SearchResult>();
        if (keywords == null) {
            return result;
        }
        Formatter f = new Formatter();
        /*
             * If the order field is already one of the field hard coded in the base query, then do not add it to the
             * select clause.
             */
        String addColumn = (orderField.equals("") || orderField.equals("fullName") || orderField.equals("name") || orderField.equals("space")) ? "" : ", doc." + orderField;
        if (space != null) {
            f.format("select distinct doc.fullName, doc.space, doc.name, obj.className, obj.number");
            f.format(addColumn);
            f.format(" from XWikiDocument as doc, BaseObject as obj, StringProperty as sp, LargeStringProperty as lsp where doc.space = :space and obj.name=doc.fullName and sp.id.id = obj.id and lsp.id.id = obj.id and (upper(sp.value) like :keywords or upper(lsp.value) like :keywords) ");
        } else {
            f.format("select distinct doc.fullName, doc.space, doc.name, obj.className, obj.number");
            f.format(addColumn);
            f.format(" from XWikiDocument as doc, BaseObject as obj, StringProperty as sp, LargeStringProperty as lsp where obj.name=doc.fullName and sp.id.id = obj.id and lsp.id.id = obj.id and (upper(sp.value) like :keywords or upper(lsp.value) like :keywords) ");
        }
        /* Build the order clause. */
        String orderClause = null;
        if (StringUtils.isBlank(orderField)) {
            orderClause = "doc.fullName asc";
        } else {
            /* Check if the order parameter is a valid "asc" or "desc" string, otherwise use "asc" */
            if ("asc".equals(order) || "desc".equals(order)) {
                orderClause = String.format("doc.%s %s", orderField, order);
            } else {
                orderClause = String.format("doc.%s asc", orderField);
            }
        }
        /* Add some filters if the user doesn't have programming rights. */
        if (hasProgrammingRights) {
            f.format(" order by %s", orderClause);
        } else {
            f.format(" and doc.space<>'XWiki' and doc.space<>'Admin' and doc.space<>'Panels' and doc.name<>'WebPreferences' order by %s", orderClause);
        }
        String query = f.toString();
        List<Object> queryResult = null;
        /* This is needed because if the :space placeholder is not in the query, setting it would cause an exception */
        if (space != null) {
            queryResult = queryManager.createQuery(query, Query.XWQL).bindValue("keywords", String.format("%%%s%%", keywords.toUpperCase())).bindValue("space", space).setLimit(number).execute();
        } else {
            queryResult = queryManager.createQuery(query, Query.XWQL).bindValue("keywords", String.format("%%%s%%", keywords.toUpperCase())).setLimit(number).execute();
        }
        /* Build the result. */
        for (Object object : queryResult) {
            Object[] fields = (Object[]) object;
            String spaceId = (String) fields[1];
            List<String> spaces = Utils.getSpacesFromSpaceId(spaceId);
            String pageName = (String) fields[2];
            String className = (String) fields[3];
            int objectNumber = (Integer) fields[4];
            String id = Utils.getObjectId(wikiName, spaces, pageName, className, objectNumber);
            String pageId = Utils.getPageId(wikiName, spaces, pageName);
            String pageFullName = Utils.getPageFullName(wikiName, spaces, pageName);
            /*
                 * Check if the user has the right to see the found document. We also prevent guest users to access
                 * object data in order to avoid leaking important information such as emails to crawlers.
                 */
            if (xwikiApi.hasAccessLevel("view", pageId) && xwikiContext.getUserReference() != null) {
                Document doc = xwikiApi.getDocument(pageFullName);
                String title = doc.getDisplayTitle();
                SearchResult searchResult = objectFactory.createSearchResult();
                searchResult.setType("object");
                searchResult.setId(id);
                searchResult.setPageFullName(pageFullName);
                searchResult.setTitle(title);
                searchResult.setWiki(wikiName);
                searchResult.setSpace(spaceId);
                searchResult.setPageName(pageName);
                searchResult.setVersion(doc.getVersion());
                searchResult.setClassName(className);
                searchResult.setObjectNumber(objectNumber);
                searchResult.setAuthor(doc.getAuthor());
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(doc.getDate());
                searchResult.setModified(calendar);
                if (withPrettyNames) {
                    searchResult.setAuthorName(Utils.getAuthorName(doc.getAuthorReference(), componentManager));
                }
                String pageUri = Utils.createURI(uriInfo.getBaseUri(), PageResource.class, wikiName, spaces, pageName).toString();
                Link pageLink = new Link();
                pageLink.setHref(pageUri);
                pageLink.setRel(Relations.PAGE);
                searchResult.getLinks().add(pageLink);
                String objectUri = Utils.createURI(uriInfo.getBaseUri(), ObjectResource.class, wikiName, spaces, pageName, className, objectNumber).toString();
                Link objectLink = new Link();
                objectLink.setHref(objectUri);
                objectLink.setRel(Relations.OBJECT);
                searchResult.getLinks().add(objectLink);
                result.add(searchResult);
            }
        }
        return result;
    } finally {
        Utils.getXWikiContext(componentManager).setWikiId(database);
    }
}
Also used : PageResource(org.xwiki.rest.resources.pages.PageResource) Formatter(java.util.Formatter) Calendar(java.util.Calendar) ArrayList(java.util.ArrayList) XWikiContext(com.xpn.xwiki.XWikiContext) XWiki(com.xpn.xwiki.api.XWiki) SearchResult(org.xwiki.rest.model.jaxb.SearchResult) Document(com.xpn.xwiki.api.Document) ObjectResource(org.xwiki.rest.resources.objects.ObjectResource) Link(org.xwiki.rest.model.jaxb.Link)

Example 5 with SearchResult

use of org.xwiki.rest.model.jaxb.SearchResult in project xwiki-platform by xwiki.

the class AbstractDatabaseSearchSource method search.

@Override
public List<SearchResult> search(String partialQueryString, String wikiName, String wikis, boolean hasProgrammingRights, String orderField, String order, boolean distinct, int number, int start, Boolean withPrettyNames, String className, UriInfo uriInfo) throws Exception {
    XWikiContext xwikiContext = this.xcontextProvider.get();
    XWiki xwikiApi = new XWiki(xwikiContext.getWiki(), xwikiContext);
    if (partialQueryString == null || StringUtils.startsWithIgnoreCase(partialQueryString, "select")) {
        return Collections.emptyList();
    }
    String queryString = resolveQuery(distinct, partialQueryString);
    Query query = this.queryManager.createQuery(queryString, this.queryLanguage);
    query.setLimit(number).setOffset(start);
    query.setWiki(wikiName);
    List<Object> queryResult = query.execute();
    WikiReference wikiReference = new WikiReference(wikiName);
    /* Build the result. */
    List<SearchResult> result = new ArrayList<>();
    for (Object object : queryResult) {
        Object[] fields = (Object[]) object;
        String fullName = (String) fields[0];
        String language = (String) fields[3];
        DocumentReference documentReference = this.resolver.resolve(fullName, wikiReference);
        /* Check if the user has the right to see the found document */
        if (this.authorization.hasAccess(Right.VIEW, documentReference)) {
            Document doc = xwikiApi.getDocument(documentReference);
            String title = doc.getDisplayTitle();
            SearchResult searchResult = this.objectFactory.createSearchResult();
            searchResult.setType("page");
            searchResult.setId(doc.getPrefixedFullName());
            searchResult.setPageFullName(doc.getFullName());
            searchResult.setTitle(title);
            searchResult.setWiki(wikiName);
            searchResult.setSpace(doc.getSpace());
            searchResult.setPageName(doc.getName());
            searchResult.setVersion(doc.getVersion());
            searchResult.setAuthor(doc.getAuthor());
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(doc.getDate());
            searchResult.setModified(calendar);
            if (withPrettyNames) {
                searchResult.setAuthorName(xwikiApi.getUserName(doc.getAuthor(), false));
            }
            /*
                 * Avoid to return object information if the user is not authenticated. This will prevent crawlers to
                 * retrieve information such as email addresses and passwords from user's profiles.
                 */
            if (StringUtils.isNotEmpty(className) && xwikiContext.getUserReference() != null) {
                XWikiDocument xdocument = xwikiContext.getWiki().getDocument(doc.getDocumentReference(), xwikiContext);
                BaseObject baseObject = xdocument.getObject(className);
                if (baseObject != null) {
                    searchResult.setObject(this.modelFactory.toRestObject(uriInfo.getBaseUri(), doc, baseObject, false, false));
                }
            }
            String pageUri;
            if (StringUtils.isBlank(language)) {
                pageUri = Utils.createURI(uriInfo.getBaseUri(), PageResource.class, wikiName, Utils.getSpacesHierarchy(documentReference.getLastSpaceReference()), documentReference.getName()).toString();
            } else {
                searchResult.setLanguage(language);
                pageUri = Utils.createURI(uriInfo.getBaseUri(), PageTranslationResource.class, wikiName, Utils.getSpacesHierarchy(documentReference.getLastSpaceReference()), documentReference.getName(), language).toString();
            }
            Link pageLink = new Link();
            pageLink.setHref(pageUri);
            pageLink.setRel(Relations.PAGE);
            searchResult.getLinks().add(pageLink);
            result.add(searchResult);
        }
    }
    return result;
}
Also used : Query(org.xwiki.query.Query) Calendar(java.util.Calendar) ArrayList(java.util.ArrayList) XWikiContext(com.xpn.xwiki.XWikiContext) XWiki(com.xpn.xwiki.api.XWiki) SearchResult(org.xwiki.rest.model.jaxb.SearchResult) Document(com.xpn.xwiki.api.Document) XWikiDocument(com.xpn.xwiki.doc.XWikiDocument) BaseObject(com.xpn.xwiki.objects.BaseObject) XWikiDocument(com.xpn.xwiki.doc.XWikiDocument) BaseObject(com.xpn.xwiki.objects.BaseObject) WikiReference(org.xwiki.model.reference.WikiReference) DocumentReference(org.xwiki.model.reference.DocumentReference) Link(org.xwiki.rest.model.jaxb.Link)

Aggregations

SearchResult (org.xwiki.rest.model.jaxb.SearchResult)9 ArrayList (java.util.ArrayList)5 Link (org.xwiki.rest.model.jaxb.Link)5 Document (com.xpn.xwiki.api.Document)4 XWiki (com.xpn.xwiki.api.XWiki)4 Calendar (java.util.Calendar)4 GetMethod (org.apache.commons.httpclient.methods.GetMethod)3 Test (org.junit.Test)3 DocumentReference (org.xwiki.model.reference.DocumentReference)3 SearchResults (org.xwiki.rest.model.jaxb.SearchResults)3 XWikiContext (com.xpn.xwiki.XWikiContext)2 Formatter (java.util.Formatter)2 Query (org.xwiki.query.Query)2 PageResource (org.xwiki.rest.resources.pages.PageResource)2 AbstractHttpTest (org.xwiki.test.rest.framework.AbstractHttpTest)2 XWikiException (com.xpn.xwiki.XWikiException)1 XWikiDocument (com.xpn.xwiki.doc.XWikiDocument)1 BaseObject (com.xpn.xwiki.objects.BaseObject)1 Locale (java.util.Locale)1 PostMethod (org.apache.commons.httpclient.methods.PostMethod)1