Esempio n. 1
0
 /**
  * Produce a comma delimited text from a JSONArray of JSONObjects using a provided list of names.
  * The list of names is not included in the output.
  *
  * @param names A JSONArray of strings.
  * @param ja A JSONArray of JSONObjects.
  * @return A comma delimited text.
  * @throws JSONException
  */
 public static String toString(JSONArray names, JSONArray ja) throws JSONException {
   if (names == null || names.length() == 0) {
     return null;
   }
   StringBuffer sb = new StringBuffer();
   for (int i = 0; i < ja.length(); i += 1) {
     JSONObject jo = ja.optJSONObject(i);
     if (jo != null) {
       sb.append(rowToString(jo.toJSONArray(names)));
     }
   }
   return sb.toString();
 }
Esempio n. 2
0
 @SuppressWarnings("unchecked")
 protected <T> T[] getArray(JSONArray arr, Class<T> typeHint) throws JSONException {
   if (arr.length() == 0) {
     if (typeHint.equals(Object.class)) {
       return (T[]) new String[0];
     } else {
       return (T[]) Array.newInstance(typeHint, 0);
     }
   }
   Object o = getObject(arr.get(0), typeHint);
   T[] array = (T[]) Array.newInstance(o.getClass(), arr.length());
   for (int i = 0; i < arr.length(); i++) {
     array[i] = getObject(arr.get(i), typeHint);
   }
   return array;
 }
Esempio n. 3
0
 protected int getPermissionBitMap(JSONArray jsonArray) throws JSONException {
   int bitmap = 0;
   for (int i = 0; i < jsonArray.length(); i++) {
     bitmap = bitmap | Permissions.parse(jsonArray.getString(i).toLowerCase()).getPermission();
   }
   return bitmap;
 }
Esempio n. 4
0
  @Override
  protected void init() {
    String versionName = "version";
    String statusName = "status";
    String contributeName = "contribute";
    JSONObject versionJSON = JSONUtil.getJSONObject(json, versionName);
    if (versionJSON != null) version = new Version(versionJSON);

    JSONObject statusJSON = JSONUtil.getJSONObject(json, statusName);
    if (statusJSON != null) status = new Status(statusJSON);

    JSONObject contributeJSON = JSONUtil.getJSONObject(json, contributeName);
    if (contributeJSON == null) {
      JSONArray contributeArray = JSONUtil.getJSONArray(json, contributeName);
      if (contributeArray != null) {
        for (int i = 0; i < contributeArray.length(); i++) {
          JSONObject object = contributeArray.optJSONObject(i);
          if (object != null)
            addContribute(new Contribute(object, Contribute.CONTRIBUTETYPE.LIFECYCLE));
        }
      }
    } else {
      addContribute(new Contribute(contributeJSON, Contribute.CONTRIBUTETYPE.LIFECYCLE));
    }
  }
Esempio n. 5
0
 /**
  * Produce a comma delimited text row from a JSONArray. Values containing the comma character will
  * be quoted.
  *
  * @param ja A JSONArray of strings.
  * @return A string ending in NEWLINE.
  */
 public static String rowToString(JSONArray ja) {
   StringBuffer sb = new StringBuffer();
   for (int i = 0; i < ja.length(); i += 1) {
     if (i > 0) {
       sb.append(',');
     }
     Object o = ja.opt(i);
     if (o != null) {
       String s = o.toString();
       if (s.indexOf(',') >= 0) {
         if (s.indexOf('"') >= 0) {
           sb.append('\'');
           sb.append(s);
           sb.append('\'');
         } else {
           sb.append('"');
           sb.append(s);
           sb.append('"');
         }
       } else {
         sb.append(s);
       }
     }
   }
   sb.append('\n');
   return sb.toString();
 }
Esempio n. 6
0
 /**
  * Produce a JSONArray of JSONObjects from a comma delimited text string using a supplied
  * JSONArray as the source of element names.
  *
  * @param names A JSONArray of strings.
  * @param x A JSONTokener of the source text.
  * @return A JSONArray of JSONObjects.
  * @throws JSONException
  */
 public static JSONArray toJSONArray(JSONArray names, JSONTokener x) throws JSONException {
   if (names == null || names.length() == 0) {
     return null;
   }
   JSONArray ja = new JSONArray();
   for (; ; ) {
     JSONObject jo = rowToJSONObject(names, x);
     if (jo == null) {
       break;
     }
     ja.put(jo);
   }
   if (ja.length() == 0) {
     return null;
   }
   return ja;
 }
Esempio n. 7
0
  /** Access contentfinder below /content */
  @Test
  public void testContentView() throws JSONException, ClientException {
    RequestExecutor exec = authorAuthor.http.doGet(CONTENTFINDER_ASSET_VIEW + "/content", 200);

    // verify via hits length
    JSONObject searchResultJson = new JSONObject(exec.getContent());
    JSONArray hits = searchResultJson.getJSONArray("hits");
    Assert.assertTrue("No hits found for search with query 'geometrixx'", hits.length() > 0);
  }
  @Test
  public void testWithCurrentResource() throws Exception {
    context.currentResource(
        context.resourceResolver().getResource("/content/sample/en/jcr:content"));

    JSONArray result = getJsonResult();

    assertEquals(2, result.length());
    assertItem(result.getJSONObject(0), "/content/sample/en/page1", "title1");
    assertItem(result.getJSONObject(1), "/content/sample/en/page2", "title2");
  }
Esempio n. 9
0
  /**
   * Test bug #36640 - Resources are not searchable after moving/merging tags
   *
   * @see https://issues.adobe.com/browse/CQ5-13533
   */
  @Test
  @UseVersion(ANY_BUT_5_5)
  public void testPageViewSearchAfterMovingTags() throws JSONException, ClientException {
    TagClient tagClient = adminAuthor.getClient(TagClient.class);

    final String ns = "itnamespace";
    final String tag = "tagOne";
    final String tagID = getTagID(ns, tag);

    try {
      // create tag
      tagClient.createTag("Integration Tests", ns, "Created during IT tests.", null);
      tagClient.createTag("Test Tag", tag, "", getTagID(ns, null));
      // tag some content
      tagClient.setTag(ROOT_PAGE_HANDLE, "+" + tagID);

      // test cf search
      JSONArray hits = searchPagesForTag(tagID);
      Assert.assertTrue("No hits found for tag ID '" + tagID + "'", hits.length() > 0);
      Assert.assertEquals(ROOT_PAGE_HANDLE, hits.getJSONObject(0).get("path"));

      // move tag
      final String newTag = "tagTwo";
      final String newTagID = getTagID(ns, newTag);
      tagClient.moveTag(tagID, newTagID, 200);

      // test cf search with new tag id
      hits = searchPagesForTag(newTagID);
      Assert.assertTrue("No hits found for tag ID '" + newTagID + "'", hits.length() > 0);
      Assert.assertEquals(ROOT_PAGE_HANDLE, hits.getJSONObject(0).get("path"));

      // test cf search with old tag id
      hits = searchPagesForTag(tagID);
      Assert.assertTrue("No hits found for tag ID '" + tagID + "'", hits.length() > 0);
      Assert.assertEquals(ROOT_PAGE_HANDLE, hits.getJSONObject(0).get("path"));

    } finally {
      // raw node delete here for safe cleanup (deleteTag() does too much validation)
      tagClient.delete("/etc/tags/" + ns);
    }
  }
  @Test
  public void testWithPath() throws Exception {
    context
        .request()
        .setParameterMap(ImmutableValueMap.of(AbstractPageProvider.RP_PATH, "/content/sample/en"));

    JSONArray result = getJsonResult();

    assertEquals(2, result.length());
    assertItem(result.getJSONObject(0), "/content/sample/en/page1", "title1");
    assertItem(result.getJSONObject(1), "/content/sample/en/page2", "title2");
  }
  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();
    }
  }
  @Test
  public void testWithPredicate() throws Exception {
    context.registerService(PredicateProvider.class, new DummyPredicateProvider());

    context
        .request()
        .setParameterMap(
            ImmutableValueMap.of(
                AbstractPageProvider.RP_PATH,
                "/content/sample/en",
                AbstractPageProvider.RP_PREDICATE,
                DummyPredicateProvider.PREDICATE_PAGENAME_PAGE1));

    JSONArray result = getJsonResult();
    assertEquals(1, result.length());
    assertItem(result.getJSONObject(0), "/content/sample/en/page1", "title1");
  }
Esempio n. 13
0
  /** Seach images in contentfinder below /content/dam */
  @Test
  public void testDamSearch() throws JSONException, ClientException {
    String query = ".jpg";
    // built the URL parameters
    URLParameterBuilder params = new URLParameterBuilder();
    params.add(new BasicNameValuePair("query", query));
    params.add(new BasicNameValuePair("mimeType", "image"));
    params.add(new BasicNameValuePair("_charset", "utf-8"));

    RequestExecutor exec =
        authorAuthor.http.doGet(CONTENTFINDER_ASSET_VIEW + "/content/dam", params, 200);

    // verify via hits length
    JSONObject searchResultJson = new JSONObject(exec.getContent());
    JSONArray hits = searchResultJson.getJSONArray("hits");
    Assert.assertTrue("No hits found for search with query 'geometrixx'", hits.length() > 0);
  }
Esempio n. 14
0
  /**
   * Takes the original request and starts the batching.
   *
   * @param request
   * @param response
   * @throws IOException
   */
  protected void batchRequest(
      SlingHttpServletRequest request, SlingHttpServletResponse response, boolean allowModify)
      throws IOException {
    // Grab the JSON block out of it and convert it to RequestData objects we can use.
    String json = request.getParameter(REQUESTS_PARAMETER);
    List<RequestInfo> batchedRequests = new ArrayList<RequestInfo>();
    try {
      JSONArray arr = new JSONArray(json);
      for (int i = 0; i < arr.length(); i++) {
        JSONObject obj = arr.getJSONObject(i);
        RequestInfo r = new RequestInfo(obj);
        if (allowModify || r.isSafe()) {
          batchedRequests.add(r);
        }
      }
    } catch (JSONException e) {
      response.sendError(
          HttpServletResponse.SC_BAD_REQUEST,
          "Failed to parse the " + REQUESTS_PARAMETER + " parameter");
      LOGGER.warn("Failed to parse the " + REQUESTS_PARAMETER + " parameter");
      return;
    }

    // Loop over the requests and handle each one.
    try {
      StringWriter sw = new StringWriter();
      JSONWriter write = new JSONWriter(sw);
      write.object();
      write.key("results");
      write.array();

      for (RequestInfo r : batchedRequests) {
        doRequest(request, response, r, write);
      }
      write.endArray();
      write.endObject();
      response.setContentType("application/json");
      response.setCharacterEncoding("UTF-8");
      response.getWriter().write(sw.getBuffer().toString());
    } catch (JSONException e) {
      LOGGER.warn("Failed to create a JSON response");
      response.sendError(
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Failed to write JSON response");
    }
  }
Esempio n. 15
0
  @Test
  public void testProperPost()
      throws ServletException, IOException, RepositoryException, JSONException,
          AccessDeniedException, StorageClientException {
    SlingHttpServletRequest request = createMock(SlingHttpServletRequest.class);
    SlingHttpServletResponse response = createMock(SlingHttpServletResponse.class);

    javax.jcr.Session jcrSession =
        Mockito.mock(
            javax.jcr.Session.class,
            Mockito.withSettings().extraInterfaces(SessionAdaptable.class));
    Session mockSession = mock(Session.class);
    ContentManager contentManager = mock(ContentManager.class);
    when(mockSession.getContentManager()).thenReturn(contentManager);
    Mockito.when(((SessionAdaptable) jcrSession).getSession()).thenReturn(mockSession);
    ResourceResolver resourceResolver = mock(ResourceResolver.class);
    Mockito.when(resourceResolver.adaptTo(javax.jcr.Session.class)).thenReturn(jcrSession);
    expect(request.getResourceResolver()).andReturn(resourceResolver);

    // Provide parameters
    String[] dimensions = new String[] {"16x16", "32x32"};
    addStringRequestParameter(request, "img", "/~johndoe/people.png");
    addStringRequestParameter(request, "save", "/~johndoe/breadcrumbs");
    addStringRequestParameter(request, "x", "10");
    addStringRequestParameter(request, "y", "10");
    addStringRequestParameter(request, "width", "70");
    addStringRequestParameter(request, "height", "70");
    addStringRequestParameter(request, "dimensions", StringUtils.join(dimensions, 0, ';'));
    expect(request.getRemoteUser()).andReturn("johndoe");

    String imagePath = "a:johndoe/people.png";
    when(contentManager.getInputStream(imagePath))
        .thenReturn(getClass().getClassLoader().getResourceAsStream("people.png"));
    when(contentManager.get(anyString())).thenReturn(new Content("foo", null));

    SparseContentResource someResource = mock(SparseContentResource.class);
    when(someResource.adaptTo(Content.class))
        .thenReturn(
            new Content(
                imagePath,
                ImmutableMap.of(
                    "mimeType", (Object) "image/png", "_bodyLocation", "2011/lt/zz/x8")));
    JackrabbitSession jrSession = mock(JackrabbitSession.class);
    SparseMapUserManager userManager = mock(SparseMapUserManager.class);
    when(userManager.getSession()).thenReturn(mockSession);
    when(jrSession.getUserManager()).thenReturn(userManager);
    when(resourceResolver.adaptTo(javax.jcr.Session.class)).thenReturn(jrSession);
    when(resourceResolver.getResource(anyString())).thenReturn(someResource);

    // Capture output.
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintWriter write = new PrintWriter(baos);
    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    expect(response.getWriter()).andReturn(write);

    replay();
    servlet.doPost(request, response);
    write.flush();

    String s = baos.toString("UTF-8");
    JSONObject o = new JSONObject(s);

    JSONArray files = o.getJSONArray("files");
    assertEquals(2, files.length());
    for (int i = 0; i < files.length(); i++) {
      String url = files.getString(i);
      assertEquals("/~johndoe/breadcrumbs/" + dimensions[i] + "_people.png", url);
    }
  }
 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 static void extractProperties(
     final JSONWriter object,
     final Map<String, Object> properties,
     final Map<String, String> renamedProperties,
     final String resourceType)
     throws JSONException {
   final JSONArray timestampFields = new JSONArray();
   boolean setResourceType = false;
   for (Map.Entry<String, Object> prop : properties.entrySet()) {
     Object value = prop.getValue();
     String key;
     if (null != renamedProperties && renamedProperties.containsKey(prop.getKey())) {
       key = renamedProperties.get(prop.getKey());
       if (null == key) {
         continue; // we're excluding this property from the export
       }
     } else {
       key = prop.getKey();
     }
     if (null != resourceType && key.equals(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY)) {
       value = resourceType;
       setResourceType = true;
     }
     if (value instanceof String[]) {
       final JSONArray list = new JSONArray();
       for (String v : (String[]) value) {
         try {
           list.put(URLEncoder.encode(v, "UTF-8"));
         } catch (final UnsupportedEncodingException e) {
           throw new JSONException(
               "String value cannot be encoded as UTF-8 for JSON transmission", e);
         }
       }
       object.key(key);
       object.value(list);
     } else if (value instanceof GregorianCalendar) {
       timestampFields.put(key);
       object.key(key);
       object.value(((Calendar) value).getTimeInMillis());
     } else if (value instanceof InputStream) {
       object.key(ContentTypeDefinitions.LABEL_ENCODED_DATA_FIELDNAME);
       object.value(key);
       object.key(ContentTypeDefinitions.LABEL_ENCODED_DATA);
       try {
         final InputStream data = (InputStream) value;
         byte[] byteData = new byte[DATA_ENCODING_CHUNK_SIZE];
         int read = 0;
         final StringBuilder stringBuilder = new StringBuilder();
         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);
             stringBuilder.append(new String(encodedBytes));
           } else if (read == DATA_ENCODING_CHUNK_SIZE) {
             byte[] encodedBytes = Base64.encodeBase64(byteData);
             stringBuilder.append(new String(encodedBytes));
           }
         }
         object.value(stringBuilder.toString());
       } catch (IOException e) {
         object.value(
             ""); // if we error out on the first read attempt, we need a placeholder value still
         object.key(ContentTypeDefinitions.LABEL_ERROR);
         object.value("IOException while getting attachment: " + e.getMessage());
       }
     } else {
       object.key(key);
       try {
         object.value(URLEncoder.encode(value.toString(), "UTF-8"));
       } catch (final UnsupportedEncodingException e) {
         throw new JSONException(
             "String value cannot be encoded as UTF-8 for JSON transmission", e);
       }
     }
   }
   if (null != resourceType
       && !setResourceType) { // make sure this gets included if it's been specified
     object.key(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY);
     object.value(resourceType);
   }
   if (timestampFields.length() > 0) {
     object.key(ContentTypeDefinitions.LABEL_TIMESTAMP_FIELDS);
     object.value(timestampFields);
   }
 }
Esempio n. 18
0
  public void execute(final WorkItem item, final WorkflowSession session, final MetaDataMap args)
      throws SocialModerationException {
    log.debug("In the workflow... (Flagged in JCR) ");
    try {
      validate(item);
      final JSONArray arr = new JSONArray((String) item.getWorkflowData().getPayload());
      final ResourceResolver resolver = getResourceResolver(session.getSession());

      for (int i = 0; i < arr.length(); i++) {
        final JSONObject obj = (JSONObject) arr.get(i);
        final String path = obj.getString(ModerationConstants.PATH);

        if (!obj.has(ModerationConstants.ACTION_FLAG)) {
          throw new SocialModerationException(
              FLAG_VERB_NOT_PRESENT_IN_PAYLOAD,
              ModerationConstants.ERR_FLAG_VERB_NOT_PRESENT_IN_PAYLOAD);
        }

        final boolean isFlagged = obj.getBoolean(ModerationConstants.ACTION_FLAG);
        final Resource resource = resolver.getResource(path);

        if (resource == null) {
          throw new SocialModerationException(
              ERR_SPECIFIED_RESOURCE_DOES_NOT_EXIST + path,
              ModerationConstants.ERR_SPECIFIED_RESOURCE_DOES_NOT_EXIST);
        } else {
          final Comment comment = resource.adaptTo(Comment.class);

          if (comment != null) {
            final Node node = resource.adaptTo(Node.class);
            node.setProperty(ModerationConstants.PROP_IS_FLAGGED, isFlagged);
            node.setProperty(ModerationConstants.PROP_IS_READ, true);
            addModHistory(
                profileMgr,
                resolver,
                node,
                ModerationConstants.PROP_IS_FLAGGED,
                String.valueOf(isFlagged),
                item.getWorkflow().getInitiator());
            node.getSession().save();
            replicator.replicate(
                session.getSession(),
                com.day.cq.replication.ReplicationActionType.ACTIVATE,
                path.substring(0, path.lastIndexOf('/')),
                null);
            // msgs[i] = "Comment " + verb + ": " + path;
          } else {
            throw new SocialModerationException(
                "Not a comment: " + path, ModerationConstants.ERR_NOT_A_COMMENT);
          }
        }
      }
    } catch (final JSONException je) {
      log.error(je.getLocalizedMessage(), je.getCause());
      throw new SocialModerationException(
          je.getLocalizedMessage(), ModerationConstants.ERR_FLAGGED_ACTION, je.getCause());
    } catch (final Exception e) {
      log.error(e.getLocalizedMessage(), e.getCause());
      throw new SocialModerationException(
          e.getLocalizedMessage(), ModerationConstants.ERR_FLAGGED_ACTION, e.getCause());
    }
  }
  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();
    }
  }