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);
 }
  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 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 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();
    }
  }