{"action":"created","issue":{"url":"https://api.github.com/repos/javalite/activejdbc/issues/341","labels_url":"https://api.github.com/repos/javalite/activejdbc/issues/341/labels{/name}","comments_url":"https://api.github.com/repos/javalite/activejdbc/issues/341/comments","events_url":"https://api.github.com/repos/javalite/activejdbc/issues/341/events","html_url":"https://github.com/javalite/activejdbc/issues/341","id":54365280,"number":341,"title":"Create org.javalite.common.Formatter class with toJson() and toXml() methods","user":{"login":"ericbn","id":4120606,"avatar_url":"https://avatars.githubusercontent.com/u/4120606?v=3","gravatar_id":"","url":"https://api.github.com/users/ericbn","html_url":"https://github.com/ericbn","followers_url":"https://api.github.com/users/ericbn/followers","following_url":"https://api.github.com/users/ericbn/following{/other_user}","gists_url":"https://api.github.com/users/ericbn/gists{/gist_id}","starred_url":"https://api.github.com/users/ericbn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ericbn/subscriptions","organizations_url":"https://api.github.com/users/ericbn/orgs","repos_url":"https://api.github.com/users/ericbn/repos","events_url":"https://api.github.com/users/ericbn/events{/privacy}","received_events_url":"https://api.github.com/users/ericbn/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"ericbn","id":4120606,"avatar_url":"https://avatars.githubusercontent.com/u/4120606?v=3","gravatar_id":"","url":"https://api.github.com/users/ericbn","html_url":"https://github.com/ericbn","followers_url":"https://api.github.com/users/ericbn/followers","following_url":"https://api.github.com/users/ericbn/following{/other_user}","gists_url":"https://api.github.com/users/ericbn/gists{/gist_id}","starred_url":"https://api.github.com/users/ericbn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ericbn/subscriptions","organizations_url":"https://api.github.com/users/ericbn/orgs","repos_url":"https://api.github.com/users/ericbn/repos","events_url":"https://api.github.com/users/ericbn/events{/privacy}","received_events_url":"https://api.github.com/users/ericbn/received_events","type":"User","site_admin":false},"milestone":null,"comments":11,"created_at":"2015-01-14T19:30:46Z","updated_at":"2015-01-21T13:57:58Z","closed_at":null,"body":""},"comment":{"url":"https://api.github.com/repos/javalite/activejdbc/issues/comments/70840830","html_url":"https://github.com/javalite/activejdbc/issues/341#issuecomment-70840830","issue_url":"https://api.github.com/repos/javalite/activejdbc/issues/341","id":70840830,"user":{"login":"ericbn","id":4120606,"avatar_url":"https://avatars.githubusercontent.com/u/4120606?v=3","gravatar_id":"","url":"https://api.github.com/users/ericbn","html_url":"https://github.com/ericbn","followers_url":"https://api.github.com/users/ericbn/followers","following_url":"https://api.github.com/users/ericbn/following{/other_user}","gists_url":"https://api.github.com/users/ericbn/gists{/gist_id}","starred_url":"https://api.github.com/users/ericbn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ericbn/subscriptions","organizations_url":"https://api.github.com/users/ericbn/orgs","repos_url":"https://api.github.com/users/ericbn/repos","events_url":"https://api.github.com/users/ericbn/events{/privacy}","received_events_url":"https://api.github.com/users/ericbn/received_events","type":"User","site_admin":false},"created_at":"2015-01-21T13:57:58Z","updated_at":"2015-01-21T13:57:58Z","body":"1. I thought serializing describes this action better than formatting... agree?\r\n\r\n2. I think some your observations apply better to other parts of the code than here. For example, the builder pattern is overused and could be better replaced by overloading methods at `ValidationBuilder` (it only has the `message()` method) for example:\r\n\r\n        addValidator(v).message(m);\r\n        // could be:\r\n        addValidator(v, m);\r\n\r\n3. We have some optional parameters -- attributeNames and ident. The pretty parameter can be optional with a default as false too...\r\n\r\n4. We have a boolean parameter -- pretty. In the case of XML we have two boolean parameters -- pretty and declaration. I think they are confusing when you need to pass them all as flags in a method, like `toXml(true, true, \"first_name\", \"last_name\")`. I don't like this. Makes me wonder \"true and true what?\" and always go back to the javadoc to check...\r\n\r\n5. We have to serialize maps and collections too. And for map serialization we can have an optional listener. AND we can output as String or to a StringBuilder. Now try to create the overloaded methods for all the possible combinations! Try it! I did!  ;- )  This is good case for a builder pattern, I think. Take a look at my implementation and see how I reused many parts of the code for the map and collection serialization using hierarchy.\r\n\r\n6. I don't like creating extra objects when not needed, but in this case I liked the solution a lot.  ;- )\r\n\r\n7. Yeah, we can review the names, though I like most of them as they read good as\r\n\r\n        p.jsonSerialize().pretty(true).withAttributes(\"first_name\", \"last_name\").toStringBuilder(sb);\r\n        // serialize is the verb, then we have the adjectives and substantives in the middle\r\n        // and finally the \"to string\" or \"to string builder\" at the end, so it reads fluently!\r\n\r\n    I didn't start with toJson, but with jsonSerialize, so \"to json to string\" would be better replaced by \"json serialize to string\". Also we have toStringBuilder(sb) receiving a StringBuilder as is a mutable object and we append to it, and toString() returning a String as it is a immutable object.\r\n\r\n8. I agree we can keep the \"old\" toJson() method. But I would not force the new methods to have the same name **just** because we already have the other one there.\r\n\r\nThoughts?\r\n\r\nAlso, lets leave this for the next release, right? So, we keep it in my fork for now..."}}