public static void extractTranslation(final JSONWriter writer, final Resource translationResource)
      throws JSONException, IOException {

    final Iterable<Resource> translations = translationResource.getChildren();
    final ValueMap props = translationResource.adaptTo(ValueMap.class);
    String languageLabel = (String) props.get("language");
    if (null == languageLabel) {
      languageLabel = (String) props.get("mtlanguage");
      if (null == languageLabel) {
        return;
      }
    }
    writer.key(ContentTypeDefinitions.LABEL_TRANSLATION);
    writer.object();
    writer.key("mtlanguage");
    if (languageLabel.equals("nb")) {
      // SPECIAL CASE FOR LEGACY EXPORTER ONLY:
      // the label for norwegian changed between 6.0 and 6.1
      // (i.e. this section must be removed for 6.1 exporter)
      languageLabel = "no";
    }

    writer.value(languageLabel);
    writer.key("jcr:created");
    writer.value(props.get("jcr:created", Long.class));
    writer.key("jcr:createdBy");
    writer.value(props.get("jcr:createdBy"));
    if (translations.iterator().hasNext()) {
      writer.key(ContentTypeDefinitions.LABEL_TRANSLATIONS);
      final JSONWriter translationObjects = writer.object();
      UGCExportHelper.extractTranslations(translationObjects, translations);
      writer.endObject();
    }
    writer.endObject();
  }
  /**
   * Extract the value of a MultiFieldPanel property into a list of maps. Will never return a null
   * map, but may return an empty one. Invalid property values are logged and skipped.
   *
   * @param resource the resource
   * @param name the property name
   * @return a list of maps.
   */
  @Function
  public static List<Map<String, String>> getMultiFieldPanelValues(Resource resource, String name) {
    ValueMap map = resource.adaptTo(ValueMap.class);
    List<Map<String, String>> results = new ArrayList<Map<String, String>>();
    if (map.containsKey(name)) {
      String[] values = map.get(name, new String[0]);
      for (String value : values) {

        try {
          JSONObject parsed = new JSONObject(value);
          Map<String, String> columnMap = new HashMap<String, String>();
          for (Iterator<String> iter = parsed.keys(); iter.hasNext(); ) {
            String key = iter.next();
            String innerValue = parsed.getString(key);
            columnMap.put(key, innerValue);
          }

          results.add(columnMap);

        } catch (JSONException e) {
          log.error(
              String.format("Unable to parse JSON in %s property of %s", name, resource.getPath()),
              e);
        }
      }
    }
    return results;
  }
Exemple #3
0
 /**
  * The promotion associated with the voucher. Promotions are used to apply some change to the
  * shopping cart once the voucher has been added.
  *
  * @return The voucher's promotion
  */
 public Promotion getPromotion() {
   ValueMap properties = resource.adaptTo(ValueMap.class);
   String promoPath = properties.get("jcr:content/promotion", String.class);
   if (promoPath != null && promoPath.length() > 0) {
     Resource promoResource = resource.getResourceResolver().getResource(promoPath);
     return (promoResource == null) ? null : promoResource.adaptTo(Promotion.class);
   } else {
     return null;
   }
 }
 private void copyContent(Resource source, Resource target, boolean skipPrimaryType)
     throws PersistenceException {
   ValueMap sourceProps = source.adaptTo(ValueMap.class);
   ModifiableValueMap targetProps = target.adaptTo(ModifiableValueMap.class);
   for (Map.Entry<String, Object> entry : sourceProps.entrySet()) {
     if (skipPrimaryType && StringUtils.equals(entry.getKey(), JcrConstants.JCR_PRIMARYTYPE)) {
       continue;
     }
     targetProps.put(entry.getKey(), entry.getValue());
   }
   copyChildren(source, target);
 }
  @Override
  public final void accept(final Resource resource) {
    // Only accept the Root folder and cq:Page and cq:PageContent nodes; All other structures are
    // uninteresting
    // to this functionality and may be very large
    final ValueMap properties = resource.adaptTo(ValueMap.class);
    final String primaryType = properties.get(JcrConstants.JCR_PRIMARYTYPE, String.class);

    if (BULK_WORKFLOW_MANAGER_PAGE_FOLDER_PATH.equals(resource.getPath())) {
      super.accept(resource);
    } else if (ArrayUtils.contains(ACCEPTED_PRIMARY_TYPES, primaryType)) {
      super.accept(resource);
    }
  }
  public List<Grades> getGrades(ResourceResolver resolver) {

    Iterable<Resource> personsResource = resolver.getResource(gradesPath).getChildren();

    List<Grades> grades = new ArrayList<Grades>();

    for (Resource res : personsResource) {
      ValueMap properties = res.adaptTo(ValueMap.class);
      String[] grad = (String[]) properties.get("grades");
      Calendar date = ParsedDate.parse(properties.get("date").toString());
      grades.add(new Grades(date, grad));
    }

    return grades;
  }
  public static void extractAttachment(
      final Writer ioWriter, final JSONWriter writer, final Resource node)
      throws JSONException, UnsupportedEncodingException {
    Resource contentNode = node.getChild("jcr:content");
    if (contentNode == null) {
      writer.key(ContentTypeDefinitions.LABEL_ERROR);
      writer.value(
          "provided resource was not an attachment - no content node beneath " + node.getPath());
      return;
    }
    ValueMap content = contentNode.adaptTo(ValueMap.class);
    if (!content.containsKey("jcr:mimeType") || !content.containsKey("jcr:data")) {
      writer.key(ContentTypeDefinitions.LABEL_ERROR);
      writer.value(
          "provided resource was not an attachment - content node contained no attachment data under "
              + node.getPath());
      return;
    }
    writer.key("filename");
    writer.value(URLEncoder.encode(node.getName(), "UTF-8"));
    writer.key("jcr:mimeType");
    writer.value(content.get("jcr:mimeType"));

    try {
      ioWriter.write(",\"jcr:data\":\"");
      final InputStream data = (InputStream) content.get("jcr:data");
      byte[] byteData = new byte[DATA_ENCODING_CHUNK_SIZE];
      int read = 0;
      while (read != -1) {
        read = data.read(byteData);
        if (read > 0 && read < DATA_ENCODING_CHUNK_SIZE) {
          // make a right-size container for the byte data actually read
          byte[] byteArray = new byte[read];
          System.arraycopy(byteData, 0, byteArray, 0, read);
          byte[] encodedBytes = Base64.encodeBase64(byteArray);
          ioWriter.write(new String(encodedBytes));
        } else if (read == DATA_ENCODING_CHUNK_SIZE) {
          byte[] encodedBytes = Base64.encodeBase64(byteData);
          ioWriter.write(new String(encodedBytes));
        }
      }
      ioWriter.write("\"");
    } catch (IOException e) {
      writer.key(ContentTypeDefinitions.LABEL_ERROR);
      writer.value(
          "IOException while getting attachment at " + node.getPath() + ": " + e.getMessage());
    }
  }
 private boolean isPrimaryType(final Resource resource, final String primaryType) {
   Node node = resource.adaptTo(Node.class);
   if (node != null) {
     // JCR-based resource resolver
     try {
       return StringUtils.equals(node.getPrimaryNodeType().getName(), primaryType);
     } catch (RepositoryException ex) {
       // ignore
       return false;
     }
   } else {
     // sling resource resolver mock
     ValueMap props = resource.getValueMap();
     return StringUtils.equals(props.get(JcrConstants.JCR_PRIMARYTYPE, String.class), primaryType);
   }
 }
 /**
  * Returns the title of the given resource. If the title is empty it will fallback to the page
  * title, title, or name of the given page.
  *
  * @param resource The resource.
  * @param page The page to fallback to.
  * @return The best suited title found (or <code>null</code> if resource is <code>null</code>).
  */
 public static String getTitle(final Resource resource, final Page page) {
   if (resource == null) {
     LOGGER.error("Provided resource argument is null");
     return null;
   }
   final ValueMap properties = resource.adaptTo(ValueMap.class);
   if (properties != null) {
     final String title = properties.get(NameConstants.PN_TITLE, String.class);
     if (StringUtils.isNotEmpty(title)) {
       return title;
     } else {
       return getPageTitle(page);
     }
   }
   return null;
 }
Exemple #10
0
 public ForumSearchImpl(final SlingHttpServletRequest request) {
   this.request = request;
   resolver = request.getResourceResolver();
   properties = ResourceUtil.getValueMap(request.getResource());
   searchPaths = properties.get(PN_SEARCHPATHS, new String[0]);
   query = getParameter(REQUEST_PARAM_QUERY);
   scopeProps = request.getParameterValues(REQUEST_PARAM_QUERY_SCOPE);
   request.setAttribute(ATTRIBUTE_NAME_SEARCH, this);
 }
  @Override
  protected void visit(final Resource resource) {
    final ValueMap properties = resource.adaptTo(ValueMap.class);

    // Ensure jcr:primaryType = cq:PageContent and
    // that the sling:resourceType is that of Bulk Workflow Manager Page and
    // that the Bulk Workflow Manager Page has been marked as "Stopped by Bundle Deactivation"
    if (NT_PAGE_CONTENT.equals(properties.get(JcrConstants.JCR_PRIMARYTYPE, String.class))
        && BulkWorkflowEngine.SLING_RESOURCE_TYPE.equals(
            properties.get(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, String.class))
        && BulkWorkflowEngine.STATE_STOPPED_DEACTIVATED.equals(
            properties.get(BulkWorkflowEngine.KEY_STATE, String.class))) {

      this.resources.add(resource);
    }

    return;
  }
  @Override
  public boolean apply(final ComponentNode componentNode) {
    final ValueMap properties = checkNotNull(componentNode).asMap();

    boolean result = false;

    if (properties.containsKey(propertyName)) {
      result = properties.get(propertyName, propertyValue.getClass()).equals(propertyValue);

      LOG.debug(
          "property name = {}, value = {}, result = {} for component node = {}",
          propertyName,
          propertyValue,
          result,
          componentNode);
    } else {
      LOG.debug(
          "property name = {}, does not exist for component node = {}",
          propertyName,
          componentNode);
    }

    return result;
  }
  private void mockJcrProperties() {
    sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm");

    // Mock jcr properties
    Map<String, Object> jcrProps = new HashMap<String, Object>();
    jcrProps.put(PN_TITLE, "My Title");
    Calendar lastMod = Calendar.getInstance();
    lastMod.set(2014, 8, 12, 1, 30);
    jcrProps.put(PN_CALENDAR, lastMod);
    jcrProps.put(PN_STR_ARRAY, new String[] {"apple", "banana", "carrot"});
    long l = 123456;
    jcrProps.put(PN_LONG, l);

    // mock value map to return jcr properties
    when(vmap.entrySet()).thenReturn(jcrProps.entrySet());
  }
 public ArrayList<UtilModel> getLinkList() {
   ArrayList<UtilModel> values = new ArrayList<UtilModel>();
   linkList = properties.get("list", new String[0]); // String[].class
   try {
     for (String temp : linkList) {
       JSONObject json = new JSONObject(temp);
       String link = json.getString("link");
       String title = json.getString("title");
       UtilModel utilModel = new UtilModel();
       utilModel.setPropertyOne(link);
       utilModel.setPropertyTwo(title);
       values.add(utilModel);
     }
   } catch (JSONException e) {
     e.printStackTrace();
   }
   return values;
 }
  public ArrayList<UtilModel> getTitleList() {
    titleList = new ArrayList<UtilModel>();
    String[] values = properties.get("list", new String[0]);
    try {
      for (String temp : values) {
        JSONObject json = new JSONObject(temp);
        String listLink = json.getString("listLink");
        String title = json.getString("title");
        UtilModel utilModel = new UtilModel();
        utilModel.setPropertyOne(title);
        utilModel.setPropertyTwo(listLink);
        titleList.add(utilModel);
      }
    } catch (JSONException e) {
      e.printStackTrace();
    }

    return titleList;
  }
  public ArrayList<UtilModel> getTitleLinkList() {
    ArrayList<UtilModel> valuesOne = new ArrayList<UtilModel>();

    titleLinkList = properties.get("link", new String[0]);
    try {
      for (String tempOne : titleLinkList) {
        JSONObject jsonObj = new JSONObject(tempOne);
        String link = jsonObj.getString("link");
        String site = jsonObj.getString("site");
        UtilModel utilModel = new UtilModel();
        utilModel.setPropertyOne(link);
        utilModel.setPropertyTwo(site);
        valuesOne.add(utilModel);
      }

    } catch (JSONException e) {
      e.printStackTrace();
    }

    return valuesOne;
  }
  public static void extractTranslations(
      final JSONWriter writer, final Iterable<Resource> translations)
      throws JSONException, IOException {
    for (final Resource translation : translations) {
      final JSONArray timestampFields = new JSONArray();
      final ValueMap vm = translation.adaptTo(ValueMap.class);
      if (!vm.containsKey("jcr:description")) {
        continue; // if there's no translation, we're done here
      }
      String languageLabel = translation.getName();
      if (languageLabel.equals("nb")) {
        // SPECIAL CASE FOR LEGACY EXPORTER ONLY:
        // the label for norwegian changed between 6.0 and 6.1
        // (i.e. this section must be removed for 6.1 exporter)
        languageLabel = "no";
      }
      writer.key(languageLabel);

      JSONWriter translationObject = writer.object();
      translationObject.key("jcr:description");
      translationObject.value(URLEncoder.encode((String) vm.get("jcr:description"), "UTF-8"));
      if (vm.containsKey("jcr:createdBy")) {
        translationObject.key("jcr:createdBy");
        translationObject.value(URLEncoder.encode((String) vm.get("jcr:createdBy"), "UTF-8"));
      }
      if (vm.containsKey("jcr:title")) {
        translationObject.key("jcr:title");
        translationObject.value(URLEncoder.encode((String) vm.get("jcr:title"), "UTF-8"));
      }
      if (vm.containsKey("postEdited")) {
        translationObject.key("postEdited");
        translationObject.value(vm.get("postEdited"));
      }
      if (vm.containsKey("translationDate")) {
        translationObject.key("translationDate");
        translationObject.value(((Calendar) vm.get("translationDate")).getTimeInMillis());
        timestampFields.put("translationDate");
      }
      if (vm.containsKey("jcr:created")) {
        translationObject.key("jcr:created");
        translationObject.value(((Calendar) vm.get("jcr:created")).getTimeInMillis());
        timestampFields.put("jcr:created");
      }
      if (timestampFields.length() > 0) {
        translationObject.key(ContentTypeDefinitions.LABEL_TIMESTAMP_FIELDS);
        translationObject.value(timestampFields);
      }
      translationObject.endObject();
    }
  }
Exemple #18
0
 public String getImageRef() {
   if (bannerType != null) {
     return nodeProperties.get("imagePathFor" + bannerType.name(), String.class);
   }
   return null;
 }
  @Test
  public void non_null_selector() {
    UrlFilter filter = new UrlFilter();

    RequestPathInfo testInfo = mock(RequestPathInfo.class);
    when(testInfo.getSelectorString()).thenReturn("sample");

    // null allowedSelectors = ok
    assertTrue(filter.checkSelector(testInfo, properties));

    // empty array allowedSelectors = fail
    properties.put(UrlFilter.PN_ALLOWED_SELECTORS, (Object) new String[0]);
    assertFalse(filter.checkSelector(testInfo, properties));

    // selector string in array = ok
    properties.put(UrlFilter.PN_ALLOWED_SELECTORS, (Object) new String[] {"sample", "sample2"});
    assertTrue(filter.checkSelector(testInfo, properties));

    // selector string not in array = fail
    properties.put(UrlFilter.PN_ALLOWED_SELECTORS, (Object) new String[] {"other"});
    assertFalse(filter.checkSelector(testInfo, properties));

    properties.clear();

    // matches regex
    properties.put(UrlFilter.PN_ALLOWED_SELECTOR_PATTERN, "^s[a-z]m.*$");
    assertTrue(filter.checkSelector(testInfo, properties));

    // doesn't match regex
    properties.put(UrlFilter.PN_ALLOWED_SELECTOR_PATTERN, "^s[1-2]m$");
    assertFalse(filter.checkSelector(testInfo, properties));

    properties.clear();

    // matches array or regex = ok
    properties.put(UrlFilter.PN_ALLOWED_SELECTORS, (Object) new String[] {"other"});
    properties.put(UrlFilter.PN_ALLOWED_SELECTOR_PATTERN, "^s[a-z]m.*$");
    assertTrue(filter.checkSelector(testInfo, properties));

    properties.put(UrlFilter.PN_ALLOWED_SELECTORS, (Object) new String[] {"sample"});
    properties.put(UrlFilter.PN_ALLOWED_SELECTOR_PATTERN, "^s[a-z]m$");
    assertTrue(filter.checkSelector(testInfo, properties));
  }
 public BlogPagination(SlingHttpServletRequest request) {
   this.request = request;
   ValueMap properties = request.getResource().adaptTo(ValueMap.class);
   pageSize = properties.get(PAGE_SIZE_PROPERTY, Integer.class);
 }
 public static void extractJournalEntry(
     final JSONWriter entryObject, final JournalEntry entry, final Writer rawWriter)
     throws JSONException, IOException {
   final Resource thisResource = entry.getTextComment().getResource();
   final ValueMap vm = thisResource.adaptTo(ValueMap.class);
   final JSONArray timestampFields = new JSONArray();
   // make sure we only migrate the fields we want
   final Map<String, Boolean> fieldsToMigrate = new HashMap<String, Boolean>();
   fieldsToMigrate.put("userIdentifier", true);
   fieldsToMigrate.put("authorizableId", true);
   fieldsToMigrate.put("published", true);
   fieldsToMigrate.put("jcr:description", true);
   fieldsToMigrate.put("jcr:title", true);
   fieldsToMigrate.put("negative", true);
   fieldsToMigrate.put("positive", true);
   fieldsToMigrate.put("sentiment", true);
   for (final Map.Entry<String, Object> prop : vm.entrySet()) {
     if (!fieldsToMigrate.containsKey(prop.getKey())) {
       continue;
     }
     final Object value = prop.getValue();
     if (prop.getKey().equals("published") && value instanceof GregorianCalendar) {
       timestampFields.put("added");
       entryObject.key("added");
       entryObject.value(((Calendar) value).getTimeInMillis());
     } else {
       entryObject.key(prop.getKey());
       try {
         entryObject.value(URLEncoder.encode(prop.getValue().toString(), "UTF-8"));
       } catch (final UnsupportedEncodingException e) {
         throw new JSONException(
             "Unsupported encoding (UTF-8) for resource at " + thisResource.getPath(), e);
       }
     }
   }
   // resource type has changed, so ignore the current one and force the new one
   entryObject.key("sling:resourceType");
   entryObject.value("social/journal/components/hbs/entry_topic");
   if (timestampFields.length() > 0) {
     entryObject.key(ContentTypeDefinitions.LABEL_TIMESTAMP_FIELDS);
     entryObject.value(timestampFields);
   }
   final Resource translationResource = thisResource.getChild("translation");
   if (null != translationResource) {
     extractTranslation(entryObject, translationResource);
   }
   if (entry.hasAttachments()) {
     entryObject.key(ContentTypeDefinitions.LABEL_ATTACHMENTS);
     JSONWriter attachmentsArray = entryObject.array();
     List<Resource> attachmentList = entry.getAttachments();
     for (final Resource attachment : attachmentList) {
       extractAttachment(rawWriter, attachmentsArray.object(), attachment);
       attachmentsArray.endObject();
     }
     entryObject.endArray();
   }
   if (entry.hasComments()) {
     final Iterator<Comment> posts = entry.getComments();
     entryObject.key(ContentTypeDefinitions.LABEL_REPLIES);
     final JSONWriter replyWriter = entryObject.object();
     while (posts.hasNext()) {
       final Comment childPost = posts.next();
       replyWriter.key(childPost.getId());
       extractComment(
           replyWriter.object(), childPost, entry.getResource().getResourceResolver(), rawWriter);
       replyWriter.endObject();
     }
     entryObject.endObject();
   }
 }
 public String getRootCollectionId() {
   return properties.get(PROPERTY_ROOT_COLLECTION_ID, "");
 }
 public String getConfig() {
   return properties.get(PROPERTY_CONFIG, "");
 }
Exemple #24
0
 public String getCode() {
   ValueMap properties = resource.adaptTo(ValueMap.class);
   return properties.get("jcr:content/code", String.class);
 }
Exemple #25
0
 /** A description visible to shoppers. */
 public String getMessage() {
   ValueMap properties = resource.adaptTo(ValueMap.class);
   return properties.get("jcr:content/message", "");
 }
  public static void extractTopic(
      final JSONWriter writer,
      final Post post,
      final ResourceResolver resolver,
      final String resourceType,
      final String childResourceType,
      final Writer responseWriter)
      throws JSONException, IOException {

    final ValueMap vm = post.getProperties();
    final JSONArray timestampFields = new JSONArray();
    for (final Map.Entry<String, Object> prop : vm.entrySet()) {
      final Object value = prop.getValue();
      if (value instanceof String[]) {
        final JSONArray list = new JSONArray();
        for (String v : (String[]) value) {
          list.put(v);
        }
        writer.key(prop.getKey());
        writer.value(list);
      } else if (value instanceof GregorianCalendar) {
        timestampFields.put(prop.getKey());
        writer.key(prop.getKey());
        writer.value(((Calendar) value).getTimeInMillis());
      } else if (prop.getKey().equals("sling:resourceType")) {
        writer.key(prop.getKey());
        writer.value(resourceType);
      } else if (prop.getKey().equals("sentiment")) {
        writer.key(prop.getKey());
        // 1 = 1, 2 = 3, 3 = 5, 4 = 8, 5 = 10
        short shortValue = Short.parseShort(value.toString());
        switch (shortValue) {
          case 1:
            writer.value(1);
            break;
          case 2:
            writer.value(3);
            break;
          case 3:
            writer.value(5);
            break;
          case 4:
            writer.value(8);
            break;
          case 5:
            writer.value(10);
            break;
          default:
            writer.value(value);
        }
      } else {
        writer.key(prop.getKey());
        try {
          writer.value(URLEncoder.encode(prop.getValue().toString(), "UTF-8"));
        } catch (final UnsupportedEncodingException e) {
          throw new JSONException(
              "Unsupported encoding (UTF-8) for resource at " + post.getPath(), e);
        }
      }
    }
    if (timestampFields.length() > 0) {
      writer.key(ContentTypeDefinitions.LABEL_TIMESTAMP_FIELDS);
      writer.value(timestampFields);
    }
    final Resource thisResource = resolver.getResource(post.getPath());
    final Resource attachments = thisResource.getChild("attachments");
    if (attachments != null) {
      writer.key(ContentTypeDefinitions.LABEL_ATTACHMENTS);
      final JSONWriter attachmentsWriter = writer.array();
      for (final Resource attachment : attachments.getChildren()) {
        UGCExportHelper.extractAttachment(responseWriter, attachmentsWriter.object(), attachment);
        attachmentsWriter.endObject();
      }
      writer.endArray();
    }
    final Iterable<Resource> children = thisResource.getChildren();
    for (final Resource child : children) {
      if (child.isResourceType("social/tally/components/hbs/voting")
          || child.isResourceType("social/tally/components/voting")) {
        writer.key(ContentTypeDefinitions.LABEL_TALLY);
        final JSONWriter voteObjects = writer.array();
        UGCExportHelper.extractTally(voteObjects, child, "Voting");
        writer.endArray();
      } else if (child.getName().equals("translation")) {
        extractTranslation(writer, child);
      }
    }
    final Iterator<Post> posts = post.getPosts();
    if (posts.hasNext()) {
      writer.key(ContentTypeDefinitions.LABEL_REPLIES);
      final JSONWriter replyWriter = writer.object();
      while (posts.hasNext()) {
        Post childPost = posts.next();
        replyWriter.key(childPost.getId());
        extractTopic(
            replyWriter.object(),
            childPost,
            resolver,
            childResourceType,
            childResourceType,
            responseWriter);
        replyWriter.endObject();
      }
      writer.endObject();
    }
  }
Exemple #27
0
 public String getTextSearchButton() {
   return properties.get(PN_TEXTSEARCHBUTTON, "");
 }
Exemple #28
0
 public String getTextResults() {
   return properties.get(PN_TEXTRESULTS, "");
 }
Exemple #29
0
 public String getTextOneMatch() {
   return properties.get(PN_TEXTONEMATCH, "");
 }
Exemple #30
0
  public SearchResult getResult() throws ForumException {

    if (null == result) {

      final PredicateGroup root = new PredicateGroup(PredicateGroup.TYPE);
      root.setAllRequired(true);

      String topicResourceType = null;
      String postResourceType = null;
      final Designer forumDesign = resolver.adaptTo(Designer.class);
      // -----------------< filter by paths >
      // -----------------------------------------------------------------
      final PredicateGroup pathFilter = new PredicateGroup("paths");
      pathFilter.setAllRequired(false);

      // -----------------< filter by resource type >
      // ----------------------------------------------------------
      final PredicateGroup resourceTypes = new PredicateGroup("resourceTypes");
      resourceTypes.setAllRequired(false);

      // no custom search paths specified, add default one
      if (pathFilter.size() == 0) {
        pathFilter.add(
            new Predicate("ugcRoot", PATH) {
              {
                set(PATH, PATH_UGC + "/content");
              }
            });
      }

      for (final String searchPath : searchPaths) {
        pathFilter.add(
            new Predicate(searchPath, PATH) {
              {
                set(PATH, PATH_UGC + searchPath);
              }
            });
        if (null != forumDesign) {
          final Resource forumResource = resolver.getResource(searchPath);
          final Style currentStyle = forumDesign.getStyle(forumResource);
          if (currentStyle != null) {
            topicResourceType = (String) currentStyle.get(PN_TOPIC_RESOURCETYPE);
            postResourceType = (String) currentStyle.get(PN_POST_RESOURCETYPE);
          }
        }
        if (topicResourceType != null) {
          final String _topicResourceType = topicResourceType;
          resourceTypes.add(
              new Predicate(topicResourceType, PROPERTY) {
                {
                  set(PROPERTY, SLING_RESOURCE_TYPE_PROPERTY);
                  set(VALUE, _topicResourceType);
                }
              });
        }
        if (postResourceType != null) {
          final String _postResourceType = postResourceType;
          resourceTypes.add(
              new Predicate(postResourceType, PROPERTY) {
                {
                  set(PROPERTY, SLING_RESOURCE_TYPE_PROPERTY);
                  set(VALUE, _postResourceType);
                }
              });
        }
      }

      resourceTypes.add(
          new Predicate(RESOURCE_TYPE_TOPIC, PROPERTY) {
            {
              set(PROPERTY, SLING_RESOURCE_TYPE_PROPERTY);
              set(VALUE, RESOURCE_TYPE_TOPIC);
            }
          });
      resourceTypes.add(
          new Predicate(RESOURCE_TYPE_POST, PROPERTY) {
            {
              set(PROPERTY, SLING_RESOURCE_TYPE_PROPERTY);
              set(VALUE, RESOURCE_TYPE_POST);
            }
          });

      // -----------------< filter by node type >
      // -------------------------------------------------------------
      final Predicate nodeTypeFilter =
          new Predicate(NODE_TYPE, TypePredicateEvaluator.TYPE) {
            {
              set(TypePredicateEvaluator.TYPE, NODE_TYPE);
            }
          };

      // -----------------< filter by query >
      // -------------------------------------------------------------
      final PredicateGroup fulltext = new PredicateGroup("fulltext");
      fulltext.setAllRequired(false);
      for (final String prop : getScopeProperties()) {
        fulltext.add(
            new Predicate(prop, FULLTEXT) {
              {
                set(FULLTEXT, getQuery());
                set(REL_PATH, "@" + prop);
              }
            });
      }

      // no custom properties to search, add default one
      if (fulltext.size() == 0) {
        fulltext.add(
            new Predicate(PN_SUBJECT, FULLTEXT) {
              {
                set(FULLTEXT, getQuery());
                set(REL_PATH, "@" + PN_SUBJECT);
              }
            });
      }

      // add predicates to root
      root.add(nodeTypeFilter);
      root.add(pathFilter);
      root.add(resourceTypes);
      root.add(fulltext);

      final QueryBuilder qb = resolver.adaptTo(QueryBuilder.class);
      final Query query = qb.createQuery(root, resolver.adaptTo(Session.class));
      query.setHitsPerPage(properties.get(PN_MAXPERPAGE, 10));
      query.setExcerpt(true);
      query.setStart(NumberUtils.toLong(request.getParameter(REQUEST_PARAM_START), 0));

      // add custom predicates
      for (final Predicate predicate : customPredicates) {
        query.getPredicates().add(predicate);
      }

      result = query.getResult();
    }

    return result;
  }