<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;DEIGQXk4fSp7ImA9WhNUEkw.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656</id><updated>2013-01-03T04:35:20.735-08:00</updated><title>Scala Programming for Enterprise Web Development</title><subtitle type="html">Scala programming language, Scala tutorials, Scala resources, using Scala with Eclipse IDE / NetBeans / Maven / Java EE / JSF / JPA</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/scalaenterprise" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="scalaenterprise" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DEIDQn0-cSp7ImA9WhVTE0s.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-628315820819094813</id><published>2012-02-27T10:16:00.001-08:00</published><updated>2012-02-27T10:16:13.359-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-27T10:16:13.359-08:00</app:edited><title>Scala Source Code and Density</title><content type="html">&lt;div class='posterous_autopost'&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;I love &lt;b&gt;Scala&lt;/b&gt;. It enables me to write concise / &lt;i&gt;dense&lt;/i&gt; &lt;b&gt;and&lt;/b&gt; &lt;i&gt;clear&lt;/i&gt; code at the same time.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Take for example the piece of code below.&lt;/div&gt; &lt;div&gt;Had I written it in Java, it would be much longer, while at the same time less dense, and with much less clarity of what it is doing.&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;val site = config.sites.find(_.name == siteName).getOrElse(&lt;/div&gt; &lt;div&gt;    throw new IllegalArgumentException(&amp;quot;Cannot find site &amp;quot; + siteName))&lt;/div&gt;&lt;div&gt;val group = config.groups.find(_.name == groupName).getOrElse(&lt;/div&gt; &lt;div&gt;    throw new IllegalArgumentException(&amp;quot;Cannot find group &amp;quot; + groupName))&lt;/div&gt;&lt;div&gt;group.repositories.foreach { repo =&amp;gt;&lt;/div&gt; &lt;div&gt;  val repoDir = new File(group.path, &lt;a href="http://repo.name"&gt;repo.name&lt;/a&gt;)&lt;/div&gt;&lt;div&gt;  println(&amp;quot;Backing up to repository %s at %s starting...&amp;quot; format (&lt;a href="http://repo.name"&gt;repo.name&lt;/a&gt;, repoDir))&lt;/div&gt; &lt;div&gt;  if (repoDir.mkdir())&lt;/div&gt;&lt;div&gt;    println(&amp;quot;Created directory %s&amp;quot; format repoDir)&lt;/div&gt;&lt;div&gt;  repo.facets.foreach { facet =&amp;gt;&lt;/div&gt; &lt;div&gt;    println(&amp;quot;Exporting facet %s...&amp;quot; format &lt;a href="http://facet.name"&gt;facet.name&lt;/a&gt;)&lt;/div&gt;&lt;div&gt;    val source = site.databases.find(_.name == facet.source).getOrElse(&lt;/div&gt; &lt;div&gt;        throw new IllegalArgumentException(&lt;/div&gt;&lt;div&gt;          &amp;quot;Facet %s references non-existing database %s&amp;quot; format (&lt;a href="http://facet.name"&gt;facet.name&lt;/a&gt;, facet.source)))&lt;/div&gt; &lt;div&gt;    println(&amp;quot;Source database is %s:%s at %s&amp;quot; format (source.kind, &lt;a href="http://source.name"&gt;source.name&lt;/a&gt;, source.url))&lt;/div&gt;&lt;div&gt;    (source.kind, facet) match {&lt;/div&gt; &lt;div&gt;      case (&amp;quot;neo4j&amp;quot;, Facet(name, sourceName, &amp;quot;node&amp;quot;, typeName, &amp;quot;json&amp;quot;)) =&amp;gt;&lt;/div&gt;&lt;div&gt;        val outFileName = new File(name + &amp;quot;.json&amp;quot;)&lt;/div&gt; &lt;div&gt;        println(&amp;quot;Exporting %s nodes to %s&amp;quot; format (typeName, outFileName))&lt;/div&gt;&lt;div&gt;        val dbDir = new File(new URI(source.url))&lt;/div&gt; &lt;div&gt;        println(&amp;quot;Neo4j database directory: %s&amp;quot; format dbDir)&lt;/div&gt;&lt;div&gt;        val graphDb = new EmbeddedReadOnlyGraphDatabase(dbDir.getPath)&lt;/div&gt; &lt;div&gt;        val (rowMeta, rows) = try {&lt;/div&gt;&lt;div&gt;          val exporter = new Neo4jNodeExporter(graphDb, typeName)&lt;/div&gt; &lt;div&gt;          println(&amp;quot;Fetching meta...&amp;quot;)&lt;/div&gt;&lt;div&gt;          val rowMeta = exporter.fetchMeta()&lt;/div&gt;&lt;div&gt;           println(&amp;quot;Columns are: &amp;quot; + rowMeta.columns.mkString(&amp;quot;, &amp;quot;))&lt;/div&gt;&lt;div&gt;          val rows = exporter.export(rowMeta)&lt;/div&gt; &lt;div&gt;          (rowMeta, rows)&lt;/div&gt;&lt;div&gt;        } finally {&lt;/div&gt;&lt;div&gt;          graphDb.shutdown()&lt;/div&gt; &lt;div&gt;        }&lt;/div&gt;&lt;div&gt;        &lt;/div&gt;&lt;div&gt;        println(&amp;quot;Reading rows...&amp;quot;)&lt;/div&gt; &lt;div&gt;        val mapper = new ObjectMapper&lt;/div&gt;&lt;div&gt;        mapper.getSerializationConfig.set(Feature.INDENT_OUTPUT, true)&lt;/div&gt; &lt;div&gt;        val jsonRows = rows.map { row =&amp;gt;&lt;/div&gt;&lt;div&gt;          val obj = mapper.createObjectNode()&lt;/div&gt;&lt;div&gt;           for ((value, i) &amp;lt;- row.values.view.zipWithIndex) {&lt;/div&gt;&lt;div&gt;            if (value != null)&lt;/div&gt;&lt;div&gt;               obj.put(rowMeta.columns(i), value)&lt;/div&gt;&lt;div&gt;          }&lt;/div&gt;&lt;div&gt;          obj&lt;/div&gt; &lt;div&gt;        }&lt;/div&gt;&lt;div&gt;        val jsonArray = mapper.createArrayNode().addAll(jsonRows.toList)&lt;/div&gt;&lt;div&gt;        val jsonData = mapper.createObjectNode()&lt;/div&gt; &lt;div&gt;        jsonData.put(&amp;quot;data&amp;quot;, jsonArray)&lt;/div&gt;&lt;div&gt;        val outFile = new File(repoDir, outFileName.toString)&lt;/div&gt; &lt;div&gt;        &lt;/div&gt;&lt;div&gt;        print(&amp;quot;Writing %s...&amp;quot; format outFile)&lt;/div&gt;&lt;div&gt;        mapper.writeValue(outFile, jsonData)&lt;/div&gt; &lt;div&gt;        println(&amp;quot; [OK]&amp;quot;)&lt;/div&gt;&lt;div&gt;        &lt;/div&gt;&lt;div&gt;      case x: Any =&amp;gt; println(&amp;quot;Skipping unrecognized facet: &amp;quot; + x)&lt;/div&gt; &lt;div&gt;    }&lt;/div&gt;&lt;div&gt;  }&lt;/div&gt;&lt;div&gt;  println(&amp;quot;Backing up to repository %s finished.&amp;quot; format &lt;a href="http://repo.name"&gt;repo.name&lt;/a&gt;)&lt;/div&gt; &lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Scala is also fantastic at storing ad-hoc object graph / trees, check a look a this :&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;div&gt;  sites = List(&lt;/div&gt; &lt;div&gt;    Site(name = &amp;quot;dev&amp;quot;, databases = List(&lt;/div&gt;&lt;div&gt;      Database(name = &amp;quot;graph&amp;quot;, kind = &amp;quot;neo4j&amp;quot;, url = &amp;quot;file:///together/project/SatukanCinta/satukancinta-neo4j-db_dev_1.6/&amp;quot;))),&lt;/div&gt; &lt;div&gt;    Site(name = &amp;quot;test&amp;quot;,&lt;/div&gt;&lt;div&gt;      databases = List(Database(name = &amp;quot;graph&amp;quot;, kind = &amp;quot;neo4j&amp;quot;, url = &amp;quot;file:///together/project/SatukanCinta/dumptest/graph&amp;quot;)))),&lt;/div&gt; &lt;div&gt;  groups = List(Group(name = &amp;quot;main&amp;quot;, path = &amp;quot;/together/project/SatukanCinta/dump_main&amp;quot;,&lt;/div&gt;&lt;div&gt;    repositories = List(&lt;/div&gt; &lt;div&gt;      Repository(name = &amp;quot;like&amp;quot;, kind = &amp;quot;*&amp;quot;, facets = List(&lt;/div&gt;&lt;div&gt;        Facet(name = &amp;quot;user&amp;quot;, source = &amp;quot;graph&amp;quot;, primitive = &amp;quot;node&amp;quot;, typeName = &amp;quot;com.satukancinta.domain.User&amp;quot;, format = &amp;quot;json&amp;quot;),&lt;/div&gt; &lt;div&gt;        Facet(name = &amp;quot;topic&amp;quot;, source = &amp;quot;graph&amp;quot;, primitive = &amp;quot;node&amp;quot;, typeName = &amp;quot;com.satukancinta.domain.Interest&amp;quot;, format = &amp;quot;json&amp;quot;),&lt;/div&gt; &lt;div&gt;        Facet(name = &amp;quot;like&amp;quot;, source = &amp;quot;graph&amp;quot;, primitive = &amp;quot;relationship&amp;quot;, typeName = &amp;quot;LIKE&amp;quot;, format = &amp;quot;graphml&amp;quot;))))))) {&lt;/div&gt; &lt;/div&gt;&lt;p /&gt;&lt;div&gt;Beat that, Java!&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Still don&amp;#39;t believe me? How about processing a bunch of collections, and sprinkle built-in parallel capability :&lt;/div&gt;&lt;p /&gt;&lt;div&gt;&lt;div&gt;    val indexHits = graphDb.getAllNodes.par.filter(_.getProperty(&amp;quot;__type__&amp;quot;) == typeName)&lt;/div&gt; &lt;div&gt;    &lt;a href="http://log.info"&gt;log.info&lt;/a&gt;(&amp;quot;Index for {} returned {} nodes&amp;quot;, typeName, indexHits.size)&lt;/div&gt;&lt;div&gt;    val columnNames = indexHits.par.flatMap( node =&amp;gt;&lt;/div&gt; &lt;div&gt;      node.getPropertyKeys.filter( _ != &amp;quot;__type__&amp;quot; ) ).toSet&lt;/div&gt;&lt;div&gt;    val sortedColumns = columnNames.toList.sorted&lt;/div&gt; &lt;div&gt;    &lt;a href="http://log.info"&gt;log.info&lt;/a&gt;(&amp;quot;Columns for {}: {}&amp;quot;, typeName, sortedColumns.mkString(&amp;quot;, &amp;quot;))&lt;/div&gt;&lt;div&gt;    RowMeta(columns = sortedColumns)&lt;/div&gt; &lt;/div&gt;&lt;p /&gt;&lt;div&gt;I really can&amp;#39;t imagine doing that (including the concurrency) in Java. Phew.&lt;/div&gt;&lt;p /&gt;&lt;div&gt;Verbose code == easy to read ? Not always. This one is much easier on the eyes.&lt;/div&gt;&lt;p /&gt;&lt;p /&gt;&lt;b&gt;Tip&lt;/b&gt;: To learn more about Scala programming, I recommend &lt;b&gt;&lt;a href="http://www.amazon.com/gp/product/0981531644/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0981531644"&gt;Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition&lt;/a&gt;&lt;/b&gt;.&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/628315820819094813/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2012/02/scala-source-code-and-density.html#comment-form" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/628315820819094813?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/628315820819094813?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2012/02/scala-source-code-and-density.html" title="Scala Source Code and Density" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>7</thr:total></entry><entry gd:etag="W/&quot;DkEERH49cCp7ImA9WhRaE08.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-2191272061094894450</id><published>2012-02-15T08:50:00.001-08:00</published><updated>2012-02-15T08:50:05.068-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-15T08:50:05.068-08:00</app:edited><title>UnproxyableResolutionException Workaround when using Scala Closures and javax.inject CDI Beans Together</title><content type="html">&lt;div class='posterous_autopost'&gt;Some powerful &lt;b&gt;Scala programming language&lt;/b&gt; features like &lt;b&gt;closures&lt;/b&gt;, &lt;b&gt;pattern matching&lt;/b&gt;, and &lt;b&gt;lazy vals&lt;/b&gt; don&amp;#39;t work well with &lt;b&gt;dependency injection frameworks&lt;/b&gt; like &lt;b&gt;javax.inject&lt;/b&gt; aka &lt;b&gt;CDI&lt;/b&gt;. This is due to stricter class structure requirements to enable proxying.&lt;p /&gt; For example, this &amp;quot;innocent&amp;quot; code will not work:&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  @Inject private var fbPhotoImporterFactory: Instance[FacebookPhotoImporter] = _ &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  @Produces @Named(&amp;quot;facebookPhotoImporter&amp;quot;) private var fbPhotoImporter: ActorRef = _&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  @PostConstruct&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  def init() {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    logger.debug(&amp;quot;Starting FacebookPhotoImporter actor&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    fbPhotoImporter = Actor.actorOf(fbPhotoImporterFactory.get())&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    fbPhotoImporter.start()&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  }&lt;/span&gt;&lt;p /&gt;It will throw:&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;Caused by: org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001437 Normal scoped bean class com.satukancinta.web.Persistence is not proxyable because the type is final or it contains a final method public final javax.enterprise.inject.Instance &lt;a href="http://com.satukancinta.web.Persistence.com"&gt;com.satukancinta.web.Persistence.com&lt;/a&gt;$satukancinta$web$Persistence$$fbPhotoImporterFactory() - Managed Bean [class com.satukancinta.web.Persistence] with qualifiers [@Any @Default].&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    at org.jboss.weld.util.Proxies.getUnproxyableClassException(Proxies.java:225)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    at org.jboss.weld.util.Proxies.getUnproxyableTypeException(Proxies.java:178)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    at org.jboss.weld.util.Proxies.getUnproxyableTypesExceptionInt(Proxies.java:193)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    at org.jboss.weld.util.Proxies.getUnproxyableTypesException(Proxies.java:167)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:110)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:126)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:345)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:330)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:366)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    at org.jboss.as.weld.WeldContainer.start(WeldContainer.java:82)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    at org.jboss.as.weld.services.WeldService.start(WeldService.java:89)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    ... 5 more&lt;/span&gt;&lt;p /&gt; As you can see, my use code isn&amp;#39;t exactly &amp;quot;edge cases&amp;quot;.&lt;p /&gt;It&amp;#39;s actually a pretty common use case: create a Akka actor and pass a factory function to it, as a closure.&lt;br /&gt;The code above doesn&amp;#39;t look like it&amp;#39;s using a closure, but it actually is when written like this: (same functionality, but still breaks CDI)&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    fbPhotoImporter = Actor.actorOf { fbPhotoImporterFactory.get() }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;&lt;/span&gt;&lt;br /&gt;I can see why CDI has a strict requirement, and I can also understand why Scala implements it the way it is (Scala developers definitely already has a lot of problems working around powerful Scala features into a very restrictive JVM bytecode requirements). This is the price we pay for having a somewhat inferior language (Java, please don&amp;#39;t get offended) in the first place.&lt;p /&gt; But I as an application developer want to have a quick fix for this issue. Re-coding the class in plain Java is one option, but it turns I don&amp;#39;t need to. There is a workaround, by creating a helper method then using it:&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  @Inject private var fbPhotoImporterFactory: Instance[FacebookPhotoImporter] = _ &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  @Produces @Named(&amp;quot;facebookPhotoImporter&amp;quot;) private var fbPhotoImporter: ActorRef = _&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  def createFbPhotoImporter() = fbPhotoImporterFactory.get() &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  @PostConstruct&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  def init() {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    logger.debug(&amp;quot;Starting FacebookPhotoImporter actor&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    fbPhotoImporter = Actor.actorOf(createFbPhotoImporter)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    fbPhotoImporter.start()&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  }&lt;/span&gt;&lt;p /&gt; Now Scala is happy and CDI is also happy. Yes it&amp;#39;s a bit more verbose but not too bad. And I guess the code is now somewhat more understandable for Java guys. :)&lt;p /&gt; &lt;b&gt;Tip:&lt;/b&gt; To &lt;b&gt;learn&lt;/b&gt; more about &lt;b&gt;Scala programming&lt;/b&gt;, I recommend &lt;b&gt;&lt;a href="http://www.amazon.com/gp/product/0981531644/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0981531644"&gt;Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition&lt;/a&gt;&lt;/b&gt;.&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/2191272061094894450/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2012/02/unproxyableresolutionexception.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/2191272061094894450?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/2191272061094894450?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2012/02/unproxyableresolutionexception.html" title="UnproxyableResolutionException Workaround when using Scala Closures and javax.inject CDI Beans Together" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DEQFQH48eSp7ImA9WhRUEkk.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-6045521817017971610</id><published>2012-01-22T07:17:00.001-08:00</published><updated>2012-01-22T07:31:51.071-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-22T07:31:51.071-08:00</app:edited><title>Scala "Bug" with CDI Dependency Injection</title><content type="html">&lt;div class="posterous_autopost"&gt;
“Sometimes”, Scala creates &lt;code&gt;public final&lt;/code&gt; methods, although the &lt;code&gt;.scala&lt;/code&gt; source defines&lt;br /&gt;
no &lt;code&gt;public final&lt;/code&gt; method at all.&lt;br /&gt;
There are two things that CDI doesn’t like (which Scala “sometimes” generates):&lt;br /&gt;
1. &lt;code&gt;public final&lt;/code&gt; methods&lt;br /&gt;2. &lt;code&gt;public&lt;/code&gt; fields&lt;br /&gt;
To investigate and reproduce these problems I created a &lt;a href="https://github.com/ceefour/scala-cdi" target="_blank"&gt;scala-cdi project at GitHub&lt;/a&gt;.&lt;br /&gt;
&lt;h2&gt;
 public final method: The Bug&lt;/h2&gt;
Referencing a parent field from a closure / inner class triggers this behavior:&lt;br /&gt;
&lt;div class="CodeRay"&gt;
&lt;div class="code"&gt;
&lt;pre&gt;@RequestScoped @Named class IndexBean { private lazy val log = LoggerFactory.getLogger(classOf[IndexBean]) def testExecutor() = { val executor = Executors.newFixedThreadPool(4); executor.submit(new Runnable() { override def run(): Unit = log.debug("Executor is running") }) } }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Compiles to:&lt;br /&gt;
&lt;div class="CodeRay"&gt;
&lt;div class="code"&gt;
&lt;pre&gt;$ javap -p IndexBean Compiled from "IndexBean.scala" public class com.soluvas.scalacdi.IndexBean extends java.lang.Object implements scala.ScalaObject{ private org.slf4j.Logger com$soluvas$scalacdi$IndexBean$$log; ... public final org.slf4j.Logger com$soluvas$scalacdi$IndexBean$$log();&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Deploying this app in Weld will throw:&lt;br /&gt;
&lt;div class="CodeRay"&gt;
&lt;div class="code"&gt;
&lt;pre&gt;org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001437 Normal scoped bean class com.soluvas.scalacdi.IndexBean is not proxyable because the type is final or it contains a final method public final org.slf4j.Logger com.soluvas.scalacdi.IndexBean.com$soluvas$scalacdi$IndexBean$$log() - Managed Bean [class com.soluvas.scalacdi.IndexBean] with qualifiers [@Any @Default @Named].         at org.jboss.weld.util.Proxies.getUnproxyableClassException(Proxies.java:225)         at org.jboss.weld.util.Proxies.getUnproxyableTypeException(Proxies.java:178)         at org.jboss.weld.util.Proxies.getUnproxyableTypesExceptionInt(Proxies.java:193)         at org.jboss.weld.util.Proxies.getUnproxyableTypesException(Proxies.java:167)         at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:110)&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;
public final method: Workaround&lt;/h2&gt;
Create a final local variable to hold the parent instance’s value:&lt;br /&gt;
&lt;div class="CodeRay"&gt;
&lt;div class="code"&gt;
&lt;pre&gt;def testExecutor() = { val executor = Executors.newFixedThreadPool(4); // this avoids 'log' becoming 'final' like: // private org.slf4j.Logger com$soluvas$scalacdi$IndexBean$$log; // public final org.slf4j.Logger com$soluvas$scalacdi$IndexBean$$log(); val log = this.log; executor.submit(new Runnable() { override def run(): Unit = log.debug("Executor is running") }) }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Which now compiles to:&lt;br /&gt;
&lt;div class="CodeRay"&gt;
&lt;div class="code"&gt;
&lt;pre&gt;$ javap -p IndexBean Compiled from "IndexBean.scala" public class com.soluvas.scalacdi.IndexBean extends java.lang.Object implements scala.ScalaObject{ private org.slf4j.Logger log; private org.slf4j.Logger log();&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;
public field&lt;/h2&gt;
I’m not able to reproduce this yet...&lt;br /&gt;
&lt;b&gt;Tip:&lt;/b&gt; To &lt;b&gt;learn&lt;/b&gt; more about &lt;b&gt;Scala programming&lt;/b&gt;, I recommend &lt;b&gt;&lt;a href="http://www.amazon.com/gp/product/0981531644/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0981531644"&gt;Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition&lt;/a&gt;&lt;/b&gt;.&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/6045521817017971610/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2012/01/scala-with-cdi-dependency-injection.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/6045521817017971610?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/6045521817017971610?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2012/01/scala-with-cdi-dependency-injection.html" title="Scala &amp;quot;Bug&amp;quot; with CDI Dependency Injection" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;CEABQX09fSp7ImA9WhRWFEk.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-1782185778579988778</id><published>2012-01-01T10:32:00.001-08:00</published><updated>2012-01-01T10:32:30.365-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-01T10:32:30.365-08:00</app:edited><title>Implementing RichFaces ExtendedDataModel for JSF Paging with Spring Data Neo4j and Scala</title><content type="html">&lt;div class='posterous_autopost'&gt;&lt;div class='p_embed p_image_embed'&gt; &lt;img alt="Satukancinta-datatable" height="723" src="http://getfile3.posterous.com/getfile/files.posterous.com/scala-enterprise/Vy2gknPNOUU48YUahPL7B2fgVfyVvwXi8GhDZUjqQEAAr0nJCT4uUbfLQW66/satukancinta-datatable.png" width="482" /&gt; &lt;/div&gt; &lt;p&gt;&lt;b&gt;JSF 2.1&lt;/b&gt; and &lt;a href="http://www.jboss.org/richfaces"&gt;&lt;b&gt;JBoss RichFaces 4.1.0&lt;/b&gt;&lt;/a&gt; make it easy to do &lt;b&gt;server-side&lt;/b&gt; &lt;b&gt;paging&lt;/b&gt; and &lt;b&gt;sorting&lt;/b&gt;, which improves performance of &lt;i&gt;Java EE web applications&lt;/i&gt; significantly compared to returning list of all rows from the database and filtering it later in the application.&lt;p /&gt; By implementing &lt;b&gt;ExtendedDataModel&lt;/b&gt;, the&lt;b&gt; data model&lt;/b&gt; can be used directly by &lt;b&gt;rich:dataTable &lt;/b&gt;and &lt;b&gt;rich:dataScroller &lt;/b&gt;JSF components.&lt;p /&gt;&lt;b&gt;ExtendedDataModel for Spring Data Neo4j Finder/Query Methods&lt;p /&gt; &lt;/b&gt;To implement this on &lt;a href="http://neo4j.org/"&gt;&lt;b&gt;Neo4j graph database&lt;/b&gt;&lt;/a&gt;, by using &lt;b&gt;&lt;a href="http://www.springsource.org/spring-data/neo4j"&gt;Spring Data Neo4j&lt;/a&gt; finder methods&lt;/b&gt; we can implement ExtendedDataModel like below: (in &lt;b&gt;Scala programming language&lt;/b&gt;)&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;package com.satukancinta.web&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import collection.JavaConversions._&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import org.ajax4jsf.model.ExtendedDataModel&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import javax.faces.context.FacesContext&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import org.springframework.data.domain.Page&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import org.ajax4jsf.model.DataVisitor&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import org.springframework.data.neo4j.repository.GraphRepository&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import org.springframework.data.domain.PageRequest&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import org.springframework.data.neo4j.aspects.core.NodeBacked&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import org.ajax4jsf.model.Range&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import org.ajax4jsf.model.SequenceRange&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import org.slf4j.LoggerFactory&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import org.springframework.data.domain.Sort&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import org.springframework.data.domain.Sort.Direction&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import org.springframework.data.domain.Pageable&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;abstract class FinderModel[E]() extends ExtendedDataModel[E] {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  private lazy val log = LoggerFactory.getLogger(classOf[FinderModel[E]])&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  private lazy val rowCount: Int = {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    val result= getRowCountLazy&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    log.debug(&amp;quot;Total rows: {}&amp;quot;, result)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    result&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  private var rowIndex: Int = _&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  private var page: Page[E] = _&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  private var pageData: List[E] = _&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  private var lastRange: (Int, Int) = _&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  log.trace(&amp;quot;Created {}&amp;quot;, this.getClass)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  def getRowCountLazy: Int&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  def find(pageable: Pageable): Page[E]&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  def setRowKey(key: Object): Unit = setRowIndex(key.asInstanceOf[Int])&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  def getRowKey: Object = getRowIndex: java.lang.Integer&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  private def loadData(range: Range): Unit = {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    val seqRange = range.asInstanceOf[SequenceRange]&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    val curRange = (seqRange.getFirstRow, seqRange.getRows)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    if (lastRange == curRange) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;      log.debug(&amp;quot;loadData returning cached&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;      return&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    lastRange = curRange&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    val pageNum = seqRange.getFirstRow / seqRange.getRows&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    // ORDER BY name is painfully slow: &lt;a href="https://groups.google.com/group/neo4j/t/f2219df41f5500a9"&gt;https://groups.google.com/group/neo4j/t/f2219df41f5500a9&lt;/a&gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    val pageReq = new PageRequest(pageNum, seqRange.getRows/*, Direction.ASC, &amp;quot;&lt;a href="http://y.name"&gt;y.name&lt;/a&gt;&amp;quot;*/)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    log.debug(&amp;quot;loadData({}, {}) -&amp;gt; PageRequest({}, {})&amp;quot;,&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        Array[Object](seqRange.getFirstRow: java.lang.Long, seqRange.getRows: java.lang.Long,&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            pageNum: java.lang.Long, seqRange.getRows: java.lang.Long))&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    val startTime = System.currentTimeMillis&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    page = find(pageReq)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    val findTime = System.currentTimeMillis - startTime&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    log.debug(&amp;quot;Page has {} rows of {} total in {} pages, took {}ms&amp;quot;,&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        Array[Object](page.getSize: java.lang.Long, page.getTotalElements: java.lang.Long,&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            page.getTotalPages: java.lang.Long, findTime: java.lang.Long))&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    pageData = page.toList&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;//    val pageIds = pageData.map( _.asInstanceOf[NodeBacked].getNodeId )&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;//    log.debug(&amp;quot;Node IDs: {}&amp;quot;, pageIds);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  }&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  def walk(context: FacesContext, visitor: DataVisitor, range: Range, argument: Object): Unit = {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    loadData(range)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    for (val index &amp;lt;- 0 to pageData.size - 1) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;      visitor.process(context, index, argument)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  }&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  def isRowAvailable: Boolean = rowIndex &amp;lt; pageData.length&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  def getRowCount: Int = rowCount&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  def getRowData: E = {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    val result = pageData(rowIndex) // repository.findOne(rowKey.asInstanceOf[Long])&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    val node = result.asInstanceOf[NodeBacked]&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    log.trace(&amp;quot;getRowData({}) = #{}: {}&amp;quot;,&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        Array[Object](rowIndex: java.lang.Long, node.getNodeId: java.lang.Long, node))&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    result&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  }&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  def getRowIndex: Int = rowIndex&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  def setRowIndex(index: Int): Unit = rowIndex = index&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  def getWrappedData: Object = { null }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  def setWrappedData(wrappedData: Object): Unit = { /* dummy */ }&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;}&lt;/span&gt;&lt;p /&gt; To use the FinderModel, it&amp;#39;s much easier if we create a repository first and add some finder/query methods returning count and Page:&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;public interface InterestRepository extends GraphRepository&amp;lt;Interest&amp;gt; {&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @Query(&amp;quot;START u=node({userId}) MATCH u-[:LIKE]-&amp;gt;y RETURN COUNT(y)&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    public Long findUserLikeCount(@Param(&amp;quot;userId&amp;quot;) long userId);&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    // ORDER BY name is still slow: &lt;a href="https://groups.google.com/group/neo4j/t/f2219df41f5500a9"&gt;https://groups.google.com/group/neo4j/t/f2219df41f5500a9&lt;/a&gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;//    @Query(&amp;quot;START u=node({userId}) MATCH u-[:LIKE]-&amp;gt;y RETURN y ORDER BY &lt;a href="http://y.name"&gt;y.name&lt;/a&gt;&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @Query(&amp;quot;START u=node({userId}) MATCH u-[:LIKE]-&amp;gt;y RETURN y&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    public Page&amp;lt;Interest&amp;gt; findUserLikes(@Param(&amp;quot;userId&amp;quot;) long userId, Pageable pageable);&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;}&lt;/span&gt;&lt;p /&gt;How to create a FinderModel instance from Java :&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @Inject InterestRepository interestRepo;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    private FinderModel&amp;lt;Interest&amp;gt; userLikesModel;&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @PostConstruct public void init() {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        userLikesModel = new FinderModel&amp;lt;Interest&amp;gt;() {&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;            @Override&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            public int getRowCountLazy() {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;                return interestRepo.findUserLikeCount(user.getNodeId()).intValue();&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            }&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;            @Override&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            public Page&amp;lt;Interest&amp;gt; find(Pageable pageable) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;                return interestRepo.findUserLikes(user.getNodeId(), pageable);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        };&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt;And how to use this data model from a JSF Template .xhtml file:&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;lt;rich:dataTable id=&amp;quot;interestTable&amp;quot; var=&amp;quot;interest&amp;quot; value=&amp;quot;#{userLikes.userLikesModel}&amp;quot; rows=&amp;quot;20&amp;quot;&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    &amp;lt;rich:column&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        &amp;lt;f:facet name=&amp;quot;header&amp;quot;&amp;gt;Name&amp;lt;/f:facet&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        &amp;lt;h:link outcome=&amp;quot;/interests/show?id=#{interest.nodeId}&amp;quot; value=&amp;quot;#{&lt;a href="http://interest.name"&gt;interest.name&lt;/a&gt;}&amp;quot;/&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    &amp;lt;/rich:column&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    &amp;lt;f:facet name=&amp;quot;footer&amp;quot;&amp;gt;&amp;lt;rich:dataScroller/&amp;gt;&amp;lt;/f:facet&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;lt;/rich:dataTable&amp;gt;&lt;/span&gt;&lt;p /&gt;Quite practical, isn&amp;#39;t it?&lt;p /&gt;&lt;br /&gt;&lt;b&gt;ExtendedDataModel for Spring Data Neo4j Repository&lt;/b&gt;&lt;p /&gt;FinderModel can then be further subclassed to handle any &lt;b&gt;Spring Data Neo4j repository&lt;/b&gt;:&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;class GraphRepositoryModel[E]() extends FinderModel[E] {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  private var repository: GraphRepository[E] = _&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  def getRowCountLazy: Int = repository.count.toInt&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  def find(pageable: Pageable): Page[E] = repository.findAll(pageable)&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  override def getWrappedData: Object = repository&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  override def setWrappedData(wrappedData: Object): Unit =&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    repository = wrappedData.asInstanceOf[GraphRepository[E]]&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;}&lt;/span&gt;&lt;p /&gt;And use it like this:&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;@Inject InterestRepository interestRepo;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;private GraphRepositoryModel&amp;lt;Interest&amp;gt; interestModel;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;@PostConstruct public void init() {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    interestModel = new GraphRepositoryModel&amp;lt;Interest&amp;gt;();&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    interestModel.setWrappedData(interestRepo);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;}&lt;/span&gt;&lt;p /&gt; Hope this helps.&lt;p /&gt;&lt;/p&gt;&lt;p&gt; To &lt;b&gt;learn&lt;/b&gt; more about &lt;b&gt;Scala programming&lt;/b&gt;, I recommend &lt;strong&gt;&lt;a href="http://www.amazon.com/gp/product/0981531644/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0981531644"&gt;Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/1782185778579988778/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2012/01/implementing-richfaces.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/1782185778579988778?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/1782185778579988778?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2012/01/implementing-richfaces.html" title="Implementing RichFaces ExtendedDataModel for JSF Paging with Spring Data Neo4j and Scala" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DEQNQX8zcCp7ImA9WhRWE0g.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-7138602570659211771</id><published>2011-12-31T10:33:00.001-08:00</published><updated>2011-12-31T10:33:10.188-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-31T10:33:10.188-08:00</app:edited><title>Scala closures vs Guava collection functions</title><content type="html">&lt;div class='posterous_autopost'&gt;Let me show you the same method using &lt;b&gt;list transformations&lt;/b&gt; (aka &amp;quot;&lt;b&gt;map&lt;/b&gt;&amp;quot; in &lt;b&gt;functional programming&lt;/b&gt; speak), one in &lt;b&gt;Java programming language&lt;/b&gt;:&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @GET @Path(&amp;quot;user/{userId}/likes&amp;quot;) @Produces(MediaType.APPLICATION_JSON)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    public Payload&amp;lt;Iterable&amp;lt;Map&amp;lt;String, Object&amp;gt;&amp;gt;&amp;gt; getUserLikes(@PathParam(&amp;quot;userId&amp;quot;) long userId) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        User user = neo4j.findOne(userId, User.class);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        Iterable&amp;lt;Interest&amp;gt; likeInterests = user.getLikeInterests();&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        Iterable&amp;lt;Map&amp;lt;String, Object&amp;gt;&amp;gt; likes = Iterables.transform(likeInterests, new Function&amp;lt;Interest, Map&amp;lt;String, Object&amp;gt;&amp;gt;() {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            @Override&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;            public Map&amp;lt;String, Object&amp;gt; apply(Interest interest) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;                HashMap&amp;lt;String, Object&amp;gt; row = new HashMap&amp;lt;String, Object&amp;gt;();&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;                row.put(&amp;quot;id&amp;quot;, interest.getNodeId());&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;                row.put(&amp;quot;name&amp;quot;, interest.getName());&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;                return  row;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        });&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        return new Payload&amp;lt;Iterable&amp;lt;Map&amp;lt;String, Object&amp;gt;&amp;gt;&amp;gt;(likes);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt; &lt;br /&gt;And one in &lt;b&gt;Scala programming language&lt;/b&gt; :&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @GET @Path(&amp;quot;user/{userId}/likes&amp;quot;) @Produces(Array(MediaType.APPLICATION_JSON))&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    def getUserLikes(@PathParam(&amp;quot;userId&amp;quot;) userId: Long): Payload[Iterable[Map[String, Object]]] = {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        val user = neo4j.findOne(userId, classOf[User])&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        val likeInterests = user.getLikeInterests&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        val likes = likeInterests.map(interest =&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;          Map(&amp;quot;id&amp;quot;-&amp;gt;interest.getNodeId, &amp;quot;name&amp;quot;-&amp;gt;interest.getName) )&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        new Payload(likes)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt;Is Scala hard to read? I&amp;#39;ll leave it to you to decide. :-)&lt;p /&gt; To &lt;b&gt;learn&lt;/b&gt; more about &lt;b&gt;Scala programming&lt;/b&gt;, I recommend &lt;strong&gt;&lt;a href="http://www.amazon.com/gp/product/0981531644/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0981531644"&gt;Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition&lt;/a&gt;&lt;/strong&gt;.&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/7138602570659211771/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2011/12/scala-closures-vs-guava-collection.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/7138602570659211771?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/7138602570659211771?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2011/12/scala-closures-vs-guava-collection.html" title="Scala closures vs Guava collection functions" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;CEYERHY4fip7ImA9WhRWE0g.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-7509776215606216125</id><published>2011-12-31T09:21:00.001-08:00</published><updated>2011-12-31T09:21:45.836-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-31T09:21:45.836-08:00</app:edited><title>Coding JSON REST JAX-RS Service Application to Access Neo4j Database in Scala</title><content type="html">&lt;div class='posterous_autopost'&gt;&lt;a href="http://www.springsource.org/spring-data/neo4j"&gt;&lt;b&gt;Spring Data Neo4j&lt;/b&gt;&lt;/a&gt; makes it easy to accessing graph data in &lt;a href="http://neo4j.org/"&gt;&lt;b&gt;Neo4j graph database&lt;/b&gt;&lt;/a&gt;.&lt;p /&gt;After &lt;a href="http://scala-enterprise.blogspot.com/2011/12/graph-analysis-with-scala-and-spring.html"&gt;separating the &lt;b&gt;AspectJ&lt;/b&gt;-enhanced Spring Data Neo4j&lt;/a&gt; &lt;b&gt;node entities, relationship entities, &lt;/b&gt;and &lt;b&gt;repositories,&lt;/b&gt; it&amp;#39;s very fun to access the entities from a &lt;b&gt;Scala &lt;/b&gt;&lt;i&gt;web application.&lt;/i&gt; In this case, I&amp;#39;ll show you a &lt;b&gt;JAX-RS application&lt;/b&gt; written in &lt;b&gt;Scala programming language&lt;/b&gt;, consuming and producing &lt;b&gt;JSON &lt;/b&gt;in &lt;b&gt;REST-&lt;/b&gt;style. The application exposes Spring Data Neo4j through HTTP, which can be accessed via &lt;b&gt;curl&lt;/b&gt; or any other web client.&lt;p /&gt; &lt;b&gt;Java programming language&lt;/b&gt; version:&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;@Path(&amp;quot;node&amp;quot;) @Stateless&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;public class NodeResource {&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    private transient Logger logger = LoggerFactory.getLogger(NodeResource.class);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @Inject Neo4jTemplate neo4j;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @Inject InterestRepository interestRepo;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @GET @Path(&amp;quot;interest&amp;quot;) @Produces(MediaType.APPLICATION_JSON)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    public Iterable&amp;lt;Interest&amp;gt; interest() {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        ClosableIterable&amp;lt;Interest&amp;gt; records = neo4j.findAll(Interest.class);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        return records;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @GET @Path(&amp;quot;user&amp;quot;) @Produces(MediaType.APPLICATION_JSON)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    public Payload&amp;lt;User&amp;gt; getUser() {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        return new Payload&amp;lt;User&amp;gt;(neo4j.findOne(5L, User.class));&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @POST @Path(&amp;quot;interest&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @Consumes(MediaType.APPLICATION_JSON)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @Produces(MediaType.APPLICATION_JSON)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    public Response createInterest(Payload&amp;lt;Interest&amp;gt; payload) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        logger.debug(&amp;quot;createInterest {}&amp;quot;, payload.data);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        Interest interest = payload.data;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        interest.persist();&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        return Response.created(URI.create(String.format(&amp;quot;interest/%d&amp;quot;, interest.getNodeId())))&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;                .entity(new Payload&amp;lt;Interest&amp;gt;(interest)).build();&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @DELETE @Path(&amp;quot;interest/{id}&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    public Response deleteInterest(@PathParam(&amp;quot;id&amp;quot;) long id) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        try {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;            Interest node = neo4j.findOne(id,  Interest.class);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            node.remove();&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;            return Response.ok(&amp;quot;deleted&amp;quot;).build();&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        } catch (DataRetrievalFailureException e) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;            return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build();&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @GET @Path(&amp;quot;interest/by/facebookId/{facebookId}&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @Produces(MediaType.APPLICATION_JSON)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    public Payload&amp;lt;Interest&amp;gt; findInterestByFacebookId(@PathParam(&amp;quot;facebookId&amp;quot;) long facebookId) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        logger.debug(&amp;quot;findInterestByFacebookId {}&amp;quot;, facebookId);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        Interest interest = interestRepo.findByFacebookId(facebookId);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        if (interest == null)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            throw new WebApplicationException(Response.status(Status.NOT_FOUND).entity(&amp;quot;Interest with facebookId=&amp;quot;+ facebookId +&amp;quot; not found&amp;quot;).build());&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        return new Payload&amp;lt;Interest&amp;gt;(interest);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;}&lt;/span&gt;&lt;p /&gt;&lt;br /&gt;&lt;b&gt;Scala programming language&lt;/b&gt; version:&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;@Path(&amp;quot;node&amp;quot;) @Stateless&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;class NodeResource {&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    private lazy val logger = LoggerFactory.getLogger(classOf[NodeResource])&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @Inject var neo4j: Neo4jTemplate = _ &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @Inject var interestRepo: InterestRepository = _&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @GET @Path(&amp;quot;interest&amp;quot;) @Produces(Array(MediaType.APPLICATION_JSON))&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    def interest: Iterable[Interest] = neo4j.findAll(classOf[Interest])&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @GET @Path(&amp;quot;user&amp;quot;) @Produces(Array(MediaType.APPLICATION_JSON))&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    def getUser: Payload[User] = new Payload[User](neo4j.findOne(5L, classOf[User]))&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @POST @Path(&amp;quot;interest&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @Consumes(Array(MediaType.APPLICATION_JSON))&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @Produces(Array(MediaType.APPLICATION_JSON))&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    def createInterest(payload: Payload[Interest]): Response = {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        logger.debug(&amp;quot;createInterest {}&amp;quot;, payload.data)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        val interest = payload.data&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        interest.persist&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        Response.created(URI.create(String.format(&amp;quot;interest/%d&amp;quot;, interest.getNodeId)))&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;                .entity(new Payload[Interest](interest)).build&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @DELETE @Path(&amp;quot;interest/{id}&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    def deleteInterest(@PathParam(&amp;quot;id&amp;quot;) id: Long): Response = {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        try {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;            val node = neo4j.findOne(id, classOf[Interest])&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            node.remove&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;            Response.ok(&amp;quot;deleted&amp;quot;).build&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        } catch {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;          case e: DataRetrievalFailureException =&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            Response.status(Status.NOT_FOUND).entity(e.getMessage).build&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    @GET @Path(&amp;quot;interest/by/facebookId/{facebookId}&amp;quot;)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @Produces(Array(MediaType.APPLICATION_JSON))&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    def findInterestByFacebookId(@PathParam(&amp;quot;facebookId&amp;quot;) facebookId: Long): Payload[Interest] = {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        logger.debug(&amp;quot;findInterestByFacebookId {}&amp;quot;, facebookId)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        val interest = interestRepo.findByFacebookId(facebookId)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        if (interest == null)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;            throw new WebApplicationException(Response.status(Status.NOT_FOUND).entity(&amp;quot;Interest with facebookId=&amp;quot;+ facebookId +&amp;quot; not found&amp;quot;).build&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        new Payload[Interest](interest)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;}&lt;/span&gt;&lt;p /&gt;&lt;br /&gt;Apart from less code and cruft, Scala code is not much different in structure.&lt;p /&gt; If there are list processing functions or closures, then Scala code will read much easier, while the Java code will use Guava library and clunky syntax (at least until Java 8 arrives).&lt;p /&gt;&lt;p&gt; To &lt;b&gt;learn&lt;/b&gt; more about &lt;b&gt;Scala programming&lt;/b&gt;, I recommend &lt;strong&gt;&lt;a href="http://www.amazon.com/gp/product/0981531644/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0981531644"&gt;Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/7509776215606216125/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2011/12/coding-json-rest-jax-rs-service.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/7509776215606216125?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/7509776215606216125?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2011/12/coding-json-rest-jax-rs-service.html" title="Coding JSON REST JAX-RS Service Application to Access Neo4j Database in Scala" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0QDRXgyeSp7ImA9WhRWE0k.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-4545426233073459063</id><published>2011-12-31T08:36:00.001-08:00</published><updated>2011-12-31T08:36:14.691-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-31T08:36:14.691-08:00</app:edited><title>Graph Analysis with Scala and Spring Data Neo4j</title><content type="html">&lt;div class='posterous_autopost'&gt;&lt;a href="http://neo4j.org/"&gt;&lt;b&gt;Neo4j graph database&lt;/b&gt;&lt;/a&gt; is the an awesome technology for &lt;b&gt;graph data persistence.&lt;/b&gt; With &lt;a href="http://www.springsource.org/spring-data/neo4j"&gt;&lt;b&gt;Spring Data Neo4j&lt;/b&gt;&lt;/a&gt; accessing graph data becomes even easier.&lt;p /&gt; The easiest way to use Spring Data Neo4j is by enabling its &lt;i&gt;AspectJ weaving&lt;/i&gt;. Because I wanted to use both Scala and Spring Data Neo4j in my web application, using both languages (AspectJ and Scala) in the same project isn&amp;#39;t possible for now. A tip for you, separate the AspectJ-enhanced classes (@NodeEntity, @RelationshipEntity, and repositories) into a separate AspectJ project, then depend on the AspectJ from the Scala application.&lt;p /&gt; The result is I&amp;#39;m able to fully utilize the versatile Scala and the excellent Spring Data libraries with Neo4j.&lt;p /&gt;Now for mandatory code comparison between Java and Scala :-)&lt;p /&gt;&lt;b&gt;Java programming language&lt;/b&gt; version:&lt;b&gt;&lt;p /&gt; &lt;/b&gt;&lt;span style="font-family: courier new,monospace;"&gt;package com.satukancinta.web;&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import java.util.List;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import java.util.Map;&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import javax.enterprise.context.ApplicationScoped;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import javax.inject.Inject;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import javax.inject.Named;&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import org.slf4j.Logger;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import org.slf4j.LoggerFactory;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import org.springframework.data.neo4j.conversion.Result;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import org.springframework.data.neo4j.support.Neo4jTemplate;&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import com.google.common.base.Function;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import com.google.common.collect.Iterables;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import com.google.common.collect.Lists;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import com.satukancinta.domain.User;&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;/**&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt; * @author ceefour&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt; * Various analysis of the social graph.&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt; */&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;@Named @ApplicationScoped&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;public class GraphAnalysis {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    private transient Logger logger = LoggerFactory.getLogger(GraphAnalysis.class);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    @Inject Neo4jTemplate neo4j;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    public List&amp;lt;MutualLikeRow&amp;gt; getMutualLikesLookup(User user) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        logger.debug(&amp;quot;getMutualLikesLookup {}/{}&amp;quot;, user.getNodeId(), user);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        Result&amp;lt;Map&amp;lt;String, Object&amp;gt;&amp;gt; rows = neo4j.query(&amp;quot;START x=node(&amp;quot;+ user.getNodeId() +&amp;quot;) MATCH x-[:LIKE]-&amp;gt;i&amp;lt;-[:LIKE]-y RETURN id(y) AS id, &lt;a href="http://y.name"&gt;y.name&lt;/a&gt; AS name, COUNT(*) AS mutualLikeCount&amp;quot;, null);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        Iterable&amp;lt;MutualLikeRow&amp;gt; result = Iterables.transform(rows, new Function&amp;lt;Map&amp;lt;String, Object&amp;gt;, MutualLikeRow&amp;gt;() {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            @Override&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;            public MutualLikeRow apply(Map&amp;lt;String, Object&amp;gt; arg) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;                return new MutualLikeRow((Long)arg.get(&amp;quot;id&amp;quot;), (Integer)arg.get(&amp;quot;mutualLikeCount&amp;quot;),&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;                        (String)arg.get(&amp;quot;name&amp;quot;));&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        });&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        return Lists.newArrayList(result);&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    }&lt;/span&gt;&lt;p /&gt; &lt;span style="font-family: courier new,monospace;"&gt;}&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;b&gt;&lt;p /&gt;Scala programming language&lt;/b&gt; version:&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;package com.satukancinta.web&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import collection.JavaConversions._&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import org.slf4j._&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import javax.inject.Inject&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import org.springframework.data.neo4j.support.Neo4jTemplate&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import com.satukancinta.domain.User&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;import javax.enterprise.context.ApplicationScoped&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;import javax.inject.Named&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;/**&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt; * @author ceefour&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt; * Analysis functions of friend network graph.&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt; */&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;@Named @ApplicationScoped&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;class GraphAnalysis {&lt;/span&gt;&lt;p /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  private lazy val logger = LoggerFactory.getLogger(classOf[GraphAnalysis])&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  @Inject private var neo4j: Neo4jTemplate = _&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  def getMutualLikesLookup(user: User): java.util.List[MutualLikeRow] = {&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    logger.debug(&amp;quot;getMutualLikesLookup {}/{}&amp;quot;, user.getNodeId, user)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    val rows = neo4j.query(&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;        &amp;quot;START x=node(&amp;quot;+ user.getNodeId() +&amp;quot;) MATCH x-[:LIKE]-&amp;gt;i&amp;lt;-[:LIKE]-y RETURN id(y) AS id, &lt;a href="http://y.name"&gt;y.name&lt;/a&gt; AS name, COUNT(*) AS mutualLikeCount&amp;quot;, null)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;    val result = rows.map( r =&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;          new MutualLikeRow(r(&amp;quot;id&amp;quot;).asInstanceOf[Long],&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;            r(&amp;quot;mutualLikeCount&amp;quot;).asInstanceOf[Integer].longValue,&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;            r(&amp;quot;name&amp;quot;).asInstanceOf[String]) )&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;        .toList&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;    result.sortBy(-_.mutualLikeCount)&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt; &lt;span style="font-family: courier new,monospace;"&gt;  }&lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace;" /&gt;&lt;span style="font-family: courier new,monospace;"&gt;}&lt;/span&gt;&lt;p /&gt; &lt;br /&gt;As you can see, the Scala version is not only much more concise, easier to understand, but actually has added functionality (sorted using .sortBy) with less code. Thanks to collection functions and closure support.&lt;p /&gt; To &lt;b&gt;learn&lt;/b&gt; more about &lt;b&gt;Scala programming&lt;/b&gt;, I recommend &lt;strong&gt;&lt;a href="http://www.amazon.com/gp/product/0981531644/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0981531644"&gt;Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition&lt;/a&gt;&lt;/strong&gt;.&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/4545426233073459063/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2011/12/graph-analysis-with-scala-and-spring.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/4545426233073459063?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/4545426233073459063?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2011/12/graph-analysis-with-scala-and-spring.html" title="Graph Analysis with Scala and Spring Data Neo4j" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0MCRXk4eCp7ImA9WhdbFEo.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-1830085971437002335</id><published>2011-10-12T19:04:00.001-07:00</published><updated>2011-10-12T19:04:24.730-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-12T19:04:24.730-07:00</app:edited><title>How to Exclude Scala/Java Source Files by Name in sbt</title><content type="html">&lt;div class='posterous_autopost'&gt;I thought this small tip would be useful to someone as I recently needed to do this and didn&amp;#39;t know &lt;b&gt;how to&lt;/b&gt;.&lt;p /&gt;The &lt;b&gt;project base directory &lt;/b&gt;is by default a &lt;b&gt;source directory &lt;/b&gt;in addition to &lt;b&gt;&lt;code&gt;src/main/scala&lt;/code&gt;&lt;/b&gt;. You can &lt;b&gt;exclude source files &lt;/b&gt;by name (&lt;code&gt;butler.scala&lt;/code&gt; in the example below) like: &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;excludeFilter in unmanagedSources := &amp;quot;butler.scala&amp;quot;&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt; &lt;p&gt;Read more on &lt;a href="http://groups.google.com/group/simple-build-tool/browse_thread/thread/cd5332a164405568?hl=en"&gt;How to exclude .&lt;b&gt;scala&lt;/b&gt; source file in project folder - &lt;b&gt;sbt&lt;/b&gt; Google Groups&lt;/a&gt;, also checkout &lt;a href="https://github.com/harrah/xsbt/wiki/Classpaths"&gt;&lt;b&gt;Classpaths&lt;/b&gt; - &lt;b&gt;sbt &lt;/b&gt;Wiki&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;To &lt;b&gt;learn&lt;/b&gt; more about &lt;b&gt;Scala programming&lt;/b&gt;, I recommend &lt;strong&gt;&lt;a href="http://www.amazon.com/gp/product/0981531644/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0981531644"&gt;Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition&lt;/a&gt;&lt;/strong&gt;. &lt;/p&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/1830085971437002335/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2011/10/how-to-exclude-scalajava-source-files.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/1830085971437002335?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/1830085971437002335?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2011/10/how-to-exclude-scalajava-source-files.html" title="How to Exclude Scala/Java Source Files by Name in sbt" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;A0QGRHc5eSp7ImA9WhZbFks.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-253441298683050726</id><published>2011-06-21T08:15:00.001-07:00</published><updated>2011-06-21T08:15:25.921-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-21T08:15:25.921-07:00</app:edited><title>Using UnboundID LDAP SDK Directory API from Scala</title><content type="html">&lt;div class='posterous_autopost'&gt;I&amp;#39;m very new in the world of &lt;b&gt;LDAP Directory Services&lt;/b&gt;. After installing &lt;a href="http://directory.apache.org/apacheds/"&gt;ApacheDS Server&lt;/a&gt;, &lt;a href="http://directory.apache.org/studio/"&gt;Apache Directory Studio LDAP GUI Client&lt;/a&gt;, and trying the plain old &lt;b&gt;ldapsearch&lt;/b&gt; and &lt;b&gt;ldapcompare&lt;/b&gt; command-line utilities, it was time for me to do some integration with Java applications (I&amp;#39;m actually trying to query LDAP directory from Ant build script task).&lt;p /&gt; The most popular and programmer-friendly LDAP API at the moment is &lt;a href="http://www.unboundid.com/products/ldapsdk/"&gt;&lt;b&gt;UnboundID LDAP SDK&lt;/b&gt;&lt;/a&gt;. To get a feel of how it works, I decided to use &lt;a href="http://www.scala-lang.org/"&gt;&lt;b&gt;Scala REPL interpreter.&lt;/b&gt;&lt;/a&gt; I really love this tool (and the Scala programming language itself) more and more every time I use it!&lt;p /&gt; The screen captures below doesn&amp;#39;t do justice to the Scala interpreter. &lt;b&gt;The tab-completion works really well!&lt;/b&gt;&lt;br /&gt; 	 	 	 	Indeed the UnboundID LDAP SDK is really easy to use, and it&amp;#39;s better with powerful &lt;b&gt;Scala&lt;/b&gt; &amp;amp; its versatile &lt;b&gt;interpreter&lt;/b&gt; for a quick ride. :-)&lt;p /&gt;&lt;b&gt;Learn Scala programming language&lt;/b&gt; quicker! Get &lt;a href="http://www.amazon.com/gp/product/0981531644/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0981531644"&gt;&lt;b&gt;Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition&lt;/b&gt;&lt;/a&gt;.&lt;br /&gt; &lt;h2 class="western"&gt;Connect &amp;amp; Bind using UnboundID LDAP SDK and Scala&lt;/h2&gt; &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;ceefour@annafi:~/vendor/unboundid-ldapsdk-2.2.0-se$ scala -cp unboundid-ldapsdk-se.jar  Welcome to Scala version 2.9.0.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_25). Type in expressions to have them evaluated. Type :help for more information. scala&amp;gt; import com.unboundid.ldap.sdk._ import com.unboundid.ldap.sdk._ scala&amp;gt; val con = new LDAPConnection con: com.unboundid.ldap.sdk.LDAPConnection = LDAPConnection(not connected) scala&amp;gt; con.connect(&amp;quot;localhost&amp;quot;, 10389) scala&amp;gt; con.bind(&amp;quot;uid=admin,ou=system&amp;quot;,&amp;quot;password&amp;quot;) res5: com.unboundid.ldap.sdk.BindResult = LDAPResult(resultCode=0 (success), messageID=1)&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt; &lt;h2 class="western"&gt; Connect &amp;amp; Bind via SSL&lt;/h2&gt; &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;scala&amp;gt; import com.unboundid.util.ssl._ import com.unboundid.util.ssl._ scala&amp;gt; var sslUtil = new SSLUtil( new TrustAllTrustManager() ) sslUtil: com.unboundid.util.ssl.SSLUtil = com.unboundid.util.ssl.SSLUtil@43763e0b scala&amp;gt; var socketFactory = sslUtil.createSSL createSSLContext createSSLServerSocketFactory createSSLSocketFactory scala&amp;gt; var socketFactory = sslUtil.createSSLSocketFactory socketFactory: javax.net.ssl.SSLSocketFactory = com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl@43d7a5a scala&amp;gt; val con = new LDAPConnection LDAPConnection LDAPConnectionInternals LDAPConnectionOptions LDAPConnectionPool LDAPConnectionPoolHealthCheck LDAPConnectionPoolHealthCheckThread LDAPConnectionPoolStatistics LDAPConnectionReader LDAPConnectionStatistics scala&amp;gt; val con = new LDAPConnection(socketFactory, &amp;quot;localhost&amp;quot;, 10636) con: com.unboundid.ldap.sdk.LDAPConnection = LDAPConnection(connected to localhost:10636) scala&amp;gt; con.bind(&amp;quot;uid=admin,ou=system&amp;quot;,&amp;quot;password&amp;quot;) res18: com.unboundid.ldap.sdk.BindResult = LDAPResult(resultCode=0 (success), messageID=1)&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt; &lt;h2 class="western"&gt; Search&lt;/h2&gt; &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;scala&amp;gt; val results=con.search(&amp;quot;ou=system&amp;quot;,SearchScope.SUB,&amp;quot;(uid=admin)&amp;quot;) results: com.unboundid.ldap.sdk.SearchResult = SearchResult(resultCode=0 (success), messageID=3, entriesReturned=1, referencesReturned=0) scala&amp;gt; results.getSearchEntries res8: java.util.List[com.unboundid.ldap.sdk.SearchResultEntry] = [SearchResultEntry(dn='uid=admin,ou=system', messageID=3, attributes={Attribute(name=uid, values={'admin'}), Attribute(name=keyAlgorithm, values={'RSA'}), Attribute(name=sn, values={'administrator'}), Attribute(name=objectClass, values={'person', 'organizationalPerson', 'inetOrgPerson', 'tlsKeyInfo', 'top'}), Attribute(name=displayName, values={'Directory Superuser'}), Attribute(name=cn, values={'system administrator'}), Attribute(name=publicKey, base64Values={'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJjX2EbUDyBZYFPfsSNMZRsW3mLc/KiKRO6pck3J3eFMKErXA7jxpiho/Eoc6RWgxut2K3aITnQZIl1hHF6Hv30CAwEAAQ=='}), Attribute(name=privateKeyFormat, values={'PKCS#8'}), Attribute(name=publicKeyFormat, values={'X.509'}), Attribute(name=privateKey, ba... scala&amp;gt; results.getSearchEntries.get(0) res11: com.unboundid.ldap.sdk.SearchResultEntry = SearchResultEntry(dn='uid=admin,ou=system', messageID=3, attributes={Attribute(name=uid, values={'admin'}), Attribute(name=keyAlgorithm, values={'RSA'}), Attribute(name=sn, values={'administrator'}), Attribute(name=objectClass, values={'person', 'organizationalPerson', 'inetOrgPerson', 'tlsKeyInfo', 'top'}), Attribute(name=displayName, values={'Directory Superuser'}), Attribute(name=cn, values={'system administrator'}), Attribute(name=publicKey, base64Values={'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJjX2EbUDyBZYFPfsSNMZRsW3mLc/KiKRO6pck3J3eFMKErXA7jxpiho/Eoc6RWgxut2K3aITnQZIl1hHF6Hv30CAwEAAQ=='}), Attribute(name=privateKeyFormat, values={'PKCS#8'}), Attribute(name=publicKeyFormat, values={'X.509'}), Attribute(name=privateKey, base64Values={'MII...&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt; &lt;h2 class="western"&gt; Compare&lt;/h2&gt; &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;scala&amp;gt; con.compare(&amp;quot;uid=admin,ou=system&amp;quot;, &amp;quot;userPassword&amp;quot;, &amp;quot;password&amp;quot;) res12: com.unboundid.ldap.sdk.CompareResult = LDAPResult(resultCode=5 (compare false), messageID=4, opType='compare', matchedDN='uid=admin,ou=system') scala&amp;gt; con.compare(&amp;quot;uid=admin,ou=system&amp;quot;, &amp;quot;uid&amp;quot;, &amp;quot;admin&amp;quot;) res13: com.unboundid.ldap.sdk.CompareResult = LDAPResult(resultCode=6 (compare true), messageID=5, opType='compare', matchedDN='uid=admin,ou=system')&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt; &lt;h2 class="western"&gt; Get Entry &amp;amp; Attribute Value&lt;/h2&gt; &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;scala&amp;gt; val entry = con.getEntry(&amp;quot;uid=admin,ou=system&amp;quot;) entry: com.unboundid.ldap.sdk.SearchResultEntry = SearchResultEntry(dn='uid=admin,ou=system', messageID=7, attributes={Attribute(name=uid, values={'admin'}), Attribute(name=keyAlgorithm, values={'RSA'}), Attribute(name=sn, values={'administrator'}), Attribute(name=objectClass, values={'person', 'organizationalPerson', 'inetOrgPerson', 'tlsKeyInfo', 'top'}), Attribute(name=displayName, values={'Directory Superuser'}), Attribute(name=cn, values={'system administrator'}), Attribute(name=publicKey, base64Values={'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJjX2EbUDyBZYFPfsSNMZRsW3mLc/KiKRO6pck3J3eFMKErXA7jxpiho/Eoc6RWgxut2K3aITnQZIl1hHF6Hv30CAwEAAQ=='}), Attribute(name=privateKeyFormat, values={'PKCS#8'}), Attribute(name=publicKeyFormat, values={'X.509'}), Attribute(name=privateKey, base64Values={'MII... scala&amp;gt; entry.getAttribute getAttribute getAttributeValue getAttributeValueAsBoolean getAttributeValueAsDN getAttributeValueAsDate getAttributeValueAsInteger getAttributeValueAsLong getAttributeValueByteArrays getAttributeValueBytes getAttributeValues getAttributes getAttributesWithOptions scala&amp;gt; entry.getAttribute def getAttribute(String): Attribute def getAttribute(String, schema.Schema): Attribute scala&amp;gt; entry.getAttribute(&amp;quot;userPassword&amp;quot;) res16: com.unboundid.ldap.sdk.Attribute = Attribute(name=userPassword, values={'{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g='}) scala&amp;gt; entry.getAttributeValue(&amp;quot;userPassword&amp;quot;) res17: java.lang.String = {SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/253441298683050726/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2011/06/using-unboundid-ldap-sdk-directory-api.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/253441298683050726?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/253441298683050726?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2011/06/using-unboundid-ldap-sdk-directory-api.html" title="Using UnboundID LDAP SDK Directory API from Scala" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;A0UMRno7eSp7ImA9WhZbFks.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-2144706709282755494</id><published>2011-06-21T08:14:00.001-07:00</published><updated>2011-06-21T08:14:47.401-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-21T08:14:47.401-07:00</app:edited><title>Scala 2.9.0.1 final version released: programming language with parallel features for Java VM</title><content type="html">&lt;div class='posterous_autopost'&gt;&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; &lt;a href="http://www.scala-lang.org/node/9708"&gt;Scala 2.9.0.1 has replaced&lt;/a&gt; 2.9.0 as it hot-fixed several important bugs.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.scala-lang.org/node/9483" target="_blank" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px; color: #2244bb;"&gt;&lt;strong&gt;Scala 2.9.0 final&lt;/strong&gt;&lt;/a&gt;&lt;span style="font-family: arial,sans-serif;"&gt;&lt;span style="border-collapse: collapse;"&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;blockquote style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;  &lt;p&gt;We are happy to announce the release of the new stable &lt;strong&gt;release&lt;/strong&gt; of the &lt;strong&gt;Scala&lt;/strong&gt; distribution. The new &lt;strong&gt;Scala 2.9.0 final&lt;/strong&gt; is available from our &lt;a href="http://www.scala-lang.org/downloads"&gt;Download Page&lt;/a&gt;. The Scala 2.9.0 codebase includes several additions, notably the new &lt;strong&gt;Parallel Collections&lt;/strong&gt;, but it also introduces improvements on many existing features, and contains many bug fixes.&lt;/p&gt;  &lt;/blockquote&gt;  &lt;p style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;strong&gt;Scala 2.9.0&lt;/strong&gt; binaries are available for the following libraries:&lt;/p&gt;  &lt;ul style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;  &lt;li&gt;&lt;a href="http://dispatch.databinder.net/" target="_blank" style="color: #2244bb;"&gt;Dispatch&lt;/a&gt;&amp;nbsp;0.7.8 and 0.8.1&lt;/li&gt;  &lt;li&gt;&lt;a href="https://github.com/n8han/unfiltered" target="_blank" style="color: #2244bb;"&gt;Unfiltered&lt;/a&gt;&amp;nbsp;0.3.2&lt;/li&gt;  &lt;li&gt;&lt;a href="http://technically.us/spde/" target="_blank" style="color: #2244bb;"&gt;Spde&lt;/a&gt;&amp;nbsp;0.3.1&lt;/li&gt;  &lt;/ul&gt;  &lt;p style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;Of course.&lt;/p&gt;  &lt;p style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;Here are some recommended learning resources on &lt;strong&gt;Scala programming language&lt;/strong&gt;:&lt;/p&gt;  &lt;ul&gt;  &lt;li&gt;&lt;span style="font-family: arial,sans-serif;"&gt;&lt;span style="border-collapse: collapse;"&gt;&lt;strong&gt;&lt;a href="http://www.amazon.com/gp/product/0981531644/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0981531644"&gt;Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition&lt;/a&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="font-family: arial,sans-serif;"&gt;&lt;span style="border-collapse: collapse;"&gt;&lt;a href="http://www.amazon.com/gp/product/0596155956/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0596155956"&gt;&lt;strong&gt;Programming Scala&lt;/strong&gt;: Scalability = Functional Programming + Objects (Animal Guide)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="font-family: arial,sans-serif;"&gt;&lt;span style="border-collapse: collapse;"&gt;&lt;a href="http://www.amazon.com/gp/product/193435631X/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=193435631X"&gt;Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine (Pragmatic Programmers)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="font-family: arial,sans-serif;"&gt;&lt;a href="http://www.amazon.com/gp/product/1430219890/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=1430219890"&gt;&lt;strong&gt;Beginning Scala&lt;/strong&gt; (Expert's Voice in Open Source)&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;  &lt;/ul&gt;  &lt;p style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;Also, the&amp;nbsp;&lt;a href="http://typesafe.com/stack" target="_blank" style="color: #2244bb;"&gt;&lt;strong&gt;Typesafe Stack&lt;/strong&gt;&lt;/a&gt;&amp;nbsp;is also out, which brings together &lt;strong&gt;Scala, &lt;a href="http://akka.io"&gt;Akka&lt;/a&gt;&lt;/strong&gt;, and a few other things to get one up-and-running quickly. Much fun.&lt;p /&gt; On the collection side of things, one of the first questions I saw was: do &lt;em&gt;parallel collections&lt;/em&gt; share a common interface with standard collections. The answer is yes, they do, but not one that existed in 2.8.1.&lt;p /&gt; You see, a trouble with parallel collections is that, now that they are available, people will probably be passing them around. If they could be passed to old code -- as it was briefly contemplated -- that old code could crash in mysterious ways. In fact, it happens with REPL itself.&lt;p /&gt; For that reason, ALL of your code comes with a&amp;nbsp;&lt;em&gt;guarantee&lt;/em&gt;&amp;nbsp;that it will only accept sequential collections. In other words, Iterable, Seq, Set, etc, they all now share a guarantee to be sequential, which means you cannot pass a parallel sequence to a method expecting Seq.&lt;p /&gt; The parallel collections start with Par: ParIterable, ParSeq, ParSet and ParMap. No ParTraversable for now. These are guaranteed to be parallel. They can be found inside scala.collection.parallel, scala.collection.parallel.immutable, etc.&lt;p /&gt; You can also get a parallel collection just by calling the ".par" method on it, and, similarly, the ".seq" method will return a sequential collection.&lt;p /&gt;Now, if you want your code to&amp;nbsp;&lt;em&gt;not care&lt;/em&gt;&amp;nbsp;whether it receives a parallel or sequential collection, you should prefix it with Gen: GenTraversable, GenIterable, GenSeq, etc. These can be either parallel or sequential.&lt;p /&gt; And, now, something fun to try out:&lt;/p&gt;  &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;def p[T](coll: collection.GenIterable[T]) = coll foreach println; p(1 to 20); p((1 to 20).par)&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;   &lt;p style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;span style="font-family: arial; font-size: small; border-collapse: separate;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;I highly recommend the following &lt;em&gt;books&lt;/em&gt; for more information about&amp;nbsp;&lt;strong&gt;Scala programming language&lt;/strong&gt;:&lt;/p&gt;  &lt;ul&gt;  &lt;li&gt;&lt;span style="font-family: arial,sans-serif;"&gt;&lt;span style="border-collapse: collapse;"&gt;&lt;strong&gt;&lt;a href="http://www.amazon.com/gp/product/0981531644/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0981531644"&gt;Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition&lt;/a&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="font-family: arial,sans-serif;"&gt;&lt;span style="border-collapse: collapse;"&gt;&lt;a href="http://www.amazon.com/gp/product/0596155956/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=0596155956"&gt;&lt;strong&gt;Programming Scala&lt;/strong&gt;: Scalability = Functional Programming + Objects (Animal Guide)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="font-family: arial,sans-serif;"&gt;&lt;span style="border-collapse: collapse;"&gt;&lt;a href="http://www.amazon.com/gp/product/193435631X/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=193435631X"&gt;Programming Scala: Tackle Multi-Core Complexity on the Java Virtual Machine (Pragmatic Programmers)&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;  &lt;li&gt;&lt;span style="font-family: arial,sans-serif;"&gt;&lt;a href="http://www.amazon.com/gp/product/1430219890/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=eclipsedriven-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399349&amp;amp;creativeASIN=1430219890"&gt;&lt;strong&gt;Beginning Scala&lt;/strong&gt;&amp;nbsp;(Expert's Voice in Open Source)&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;  &lt;/ul&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;em&gt;Copied mostly verbatim from &lt;a href="http://code.technically.us/post/5421169954"&gt;this announcement&lt;/a&gt; and &lt;a href="http://dcsobral.blogspot.com/2011/05/scala-29-and-parallel-collections.html"&gt;that announcement&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/2144706709282755494/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2011/06/scala-2901-final-version-released.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/2144706709282755494?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/2144706709282755494?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2011/06/scala-2901-final-version-released.html" title="Scala 2.9.0.1 final version released: programming language with parallel features for Java VM" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0EMRXYzfSp7ImA9Wx9QE0o.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-7775736977377246419</id><published>2010-12-26T05:54:00.001-08:00</published><updated>2010-12-26T05:54:44.885-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-26T05:54:44.885-08:00</app:edited><title>How to Dump/Inspect Object or Variable in Java</title><content type="html">&lt;div class='posterous_autopost'&gt;      &lt;b&gt;Scala (console)&lt;/b&gt; has a very useful feature to &lt;b&gt;inspect or dump variables / object values :&lt;/b&gt;&lt;p /&gt;  &lt;tt&gt;scala&amp;gt; def b = Map(&amp;quot;name&amp;quot; -&amp;gt; &amp;quot;Yudha&amp;quot;, &amp;quot;age&amp;quot; -&amp;gt; 27)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;b: scala.collection.immutable.Map[java.lang.String,Any]&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;scala&amp;gt; b&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;res1: scala.collection.immutable.Map[java.lang.String,Any] = Map((name,Yudha), (age,27))&lt;/tt&gt;&lt;p /&gt;  Inside our application, especially in &lt;b&gt;Java programming language&lt;/b&gt; (although the techniques below obviously works with any &lt;b&gt;JVM language&lt;/b&gt; like &lt;b&gt;Scala&lt;/b&gt; and &lt;b&gt;Groovy&lt;/b&gt;) sometimes we want to &lt;b&gt;inspect/dump the content of an object/value&lt;/b&gt;. Probably for &lt;b&gt;debugging&lt;/b&gt; or &lt;b&gt;logging&lt;/b&gt; purposes.&lt;p /&gt;  My two favorite techniques is just to &lt;b&gt;serialize the Java object to JSON&lt;/b&gt; and/or &lt;b&gt;XML&lt;/b&gt;. An added benefit is that it's possible to &lt;b&gt;deserialize&lt;/b&gt; the &lt;b&gt;dumped object representation&lt;/b&gt; back to an actual object if you want.&lt;p /&gt;  &lt;h3&gt; JSON Serialization with Jackson &lt;/h3&gt; Depend on Jackson (using Maven):&lt;br /&gt; &lt;tt&gt;		&amp;lt;dependency&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;			&amp;lt;groupId&amp;gt;org.codehaus.jackson&amp;lt;/groupId&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;			&amp;lt;artifactId&amp;gt;jackson-mapper-asl&amp;lt;/artifactId&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;			&amp;lt;version&amp;gt;1.6.3&amp;lt;/version&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		&amp;lt;/dependency&amp;gt;&lt;/tt&gt;&lt;br /&gt; Then use it:&lt;br /&gt; &lt;tt&gt;import org.codehaus.jackson.JsonGenerationException;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;import org.codehaus.jackson.map.JsonMappingException;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;import org.codehaus.jackson.map.ObjectMapper;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;import org.codehaus.jackson.map.SerializationConfig;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;import org.slf4j.Logger;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;import org.slf4j.LoggerFactory;&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;..&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	Logger logger = LoggerFactory.getLogger(getClass());&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	@Test&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	public void level() throws ServiceException, JsonGenerationException, JsonMappingException, IOException {&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		MagentoServiceLocator locator = new MagentoServiceLocator();&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		Mage_Api_Model_Server_HandlerPortType port = locator.getMage_Api_Model_Server_HandlerPort();&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		String sessionId = port.login(&amp;quot;...&amp;quot;, &amp;quot;...&amp;quot;);&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		logger.info(String.format(&amp;quot;Session ID = %s&amp;quot;, sessionId));&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		Map[] categories = (Map[]) port.call(sessionId, &amp;quot;catalog_category.level&amp;quot;, new Object[] { null, null, 2 } );&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&lt;b&gt;		ObjectMapper mapper = new ObjectMapper();&lt;/b&gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&lt;b&gt;		mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);&lt;/b&gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&lt;b&gt;		logger.info( mapper.writeValueAsString(categories) ); &lt;/b&gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	}&lt;/tt&gt;&lt;p /&gt;  Example output :&lt;p /&gt;  &lt;tt&gt;6883 [main] INFO id.co.bippo.shop.magentoclient.AppTest - [ {&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;position&amp;quot; : &amp;quot;1&amp;quot;,&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;level&amp;quot; : &amp;quot;2&amp;quot;,&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;is_active&amp;quot; : &amp;quot;1&amp;quot;,&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;name&amp;quot; : &amp;quot;Gamis&amp;quot;,&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;category_id&amp;quot; : &amp;quot;3&amp;quot;,&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;parent_id&amp;quot; : 2&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;}, {&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;position&amp;quot; : &amp;quot;2&amp;quot;,&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;level&amp;quot; : &amp;quot;2&amp;quot;,&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;is_active&amp;quot; : &amp;quot;1&amp;quot;,&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;name&amp;quot; : &amp;quot;Celana&amp;quot;,&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;category_id&amp;quot; : &amp;quot;5&amp;quot;,&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;quot;parent_id&amp;quot; : 2&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;} ]&lt;/tt&gt;&lt;p /&gt;  &lt;h3&gt; XML Serialization with XStream &lt;/h3&gt; As a pre-note, &lt;b&gt;XStream&lt;/b&gt; can also handle &lt;b&gt;JSON&lt;/b&gt; with either &lt;b&gt;Jettison&lt;/b&gt; or its own JSON driver, however people usually prefer &lt;b&gt;Jackson&lt;/b&gt; than XStream for JSON serialization.&lt;p /&gt;  Maven dependency for XStream:&lt;br /&gt; &lt;tt&gt;		&amp;lt;dependency&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;			&amp;lt;groupId&amp;gt;xstream&amp;lt;/groupId&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;			&amp;lt;artifactId&amp;gt;xstream&amp;lt;/artifactId&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;			&amp;lt;version&amp;gt;1.2.2&amp;lt;/version&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		&amp;lt;/dependency&amp;gt;&lt;/tt&gt;&lt;br /&gt; Use it:&lt;br /&gt; &lt;tt&gt;import java.io.IOException;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;import java.rmi.RemoteException;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;import java.util.Map;&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;import javax.xml.rpc.ServiceException;&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;import org.junit.Test;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;import org.slf4j.Logger;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;import org.slf4j.LoggerFactory;&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;import com.thoughtworks.xstream.XStream;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;...&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	@Test&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	public void infoXml() throws ServiceException, RemoteException {&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		MagentoServiceLocator locator = new MagentoServiceLocator();&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		Mage_Api_Model_Server_HandlerPortType port = locator.getMage_Api_Model_Server_HandlerPort();&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		String sessionId = port.login(&amp;quot;...&amp;quot;, &amp;quot;...&amp;quot;);&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		logger.info(String.format(&amp;quot;Session ID = %s&amp;quot;, sessionId));&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;		Map category = (Map) port.call(sessionId, &amp;quot;catalog_category.info&amp;quot;,&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;				new Object[] { 3 } );&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&lt;b&gt;		XStream xstream = new XStream();&lt;/b&gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&lt;b&gt;		logger.info( xstream.toXML(category) );&lt;/b&gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	}&lt;/tt&gt;&lt;p /&gt;  Sample output:&lt;p /&gt;  &lt;tt&gt;5949 [main] INFO id.co.bippo.shop.magentoclient.AppTest - &amp;lt;map&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;position&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;1&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;custom_design&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;custom_use_parent_settings&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;0&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;custom_layout_update&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;include_in_menu&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;1&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;custom_apply_to_products&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;0&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;meta_keywords&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;gamis, busana muslim&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;available_sort_by&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;url_path&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;gamis.html&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;children&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;landing_page&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;null/&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;display_mode&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;PRODUCTS&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;level&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;2&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;description&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;Gamis untuk muslimah&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;name&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;Gamis&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;path&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;1/2/3&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;created_at&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;2010-12-24 11:37:41&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;children_count&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;0&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;is_anchor&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;1&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;url_key&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;gamis&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;parent_id&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;int&amp;gt;2&amp;lt;/int&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;filter_price_range&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;null/&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;all_children&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;3&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;is_active&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;1&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;page_layout&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;image&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;null/&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;category_id&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;3&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;default_sort_by&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;null/&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;custom_design_from&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;null/&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;updated_at&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;2010-12-24 11:37:41&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;meta_description&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;Jual baju gamis untuk muslim&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;custom_design_to&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;null/&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;path_in_store&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;null/&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;meta_title&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;Gamis&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;string&amp;gt;increment_id&amp;lt;/string&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;null/&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; &amp;lt;/entry&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;lt;/map&amp;gt;&lt;/tt&gt;&lt;p /&gt;  Which one is better?&lt;p /&gt;  I personally prefer &lt;b&gt;JSON&lt;/b&gt;, but fortunately, you always have a choice. :-)  &lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/7775736977377246419/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/how-to-dumpinspect-object-or-variable.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/7775736977377246419?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/7775736977377246419?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/how-to-dumpinspect-object-or-variable.html" title="How to Dump/Inspect Object or Variable in Java" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DE4ARn8zfCp7ImA9Wx9RGEU.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-5843607076490024173</id><published>2010-12-20T15:15:00.001-08:00</published><updated>2010-12-20T15:15:47.184-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-20T15:15:47.184-08:00</app:edited><title>Eclipse RAP Single Sourcing Awesomeness (with EMF Editor and Teneo+Hibernate as bonus!)</title><content type="html">&lt;div class='posterous_autopost'&gt;      &lt;b&gt;&lt;a href="http://wiki.eclipse.org/index.php/Rich_Client_Platform"&gt;Eclipse Rich Client Platform&lt;/a&gt;&lt;/b&gt; has come a looong way since it was first introduced (and used in &lt;b&gt;&lt;a href="http://www.eclipse.org/home/categories/index.php?category=ide"&gt;Eclipse IDE&lt;/a&gt;&lt;/b&gt;). The new &lt;b&gt;&lt;a href="http://www.eclipse.org/rap/"&gt;Eclipse RAP (Rich Application Platform)&lt;/a&gt;&lt;/b&gt; is also becoming more and more attractive for deploying existing or new Eclipse RCP applications to the web.&lt;p /&gt;  One of my the projects I'm working on is developed on top of Eclipse RCP. It uses additional plugins such as &lt;b&gt;&lt;a href="http://www.eclipse.org/emf/"&gt;EMF (Eclipse Modeling Framework)&lt;/a&gt;&lt;/b&gt; including EMF Editor UI, &lt;b&gt;&lt;a href="http://wiki.eclipse.org/Teneo"&gt;Teneo (EMF Persistence for Relational Databases)&lt;/a&gt;&lt;/b&gt;, and &lt;a href="www.hibernate.org"&gt;Hibernate&lt;/a&gt;.&lt;p /&gt;  After some work, I managed to run the whole application on both Eclipse RCP (desktop) and Eclipse RAP (web-based). See the screenshots for proof. &lt;img src="http://posterous.com/getfile/files.posterous.com/eclipsedriven/ZzvN0KsUvfsMoCCDVD7b6C05cQcQ7HXEK0BKkLadEjSKpsBtXbJUGSyEt2aN/face-wink.png" width="16" height="16"/&gt; &lt;p /&gt;  Thanks to the recently released &lt;b&gt;&lt;a href="http://wiki.eclipse.org/EMF_Editor_goes_RAP"&gt;EMF Support for RAP&lt;/a&gt;&lt;/b&gt; I don't have to let go any of the nice EMF generated editor UIs for the web-based RAP version.&lt;p /&gt;  What's amazing is how &lt;i&gt;little&lt;/i&gt; the work I have to do to port the RCP app to RAP.&lt;p /&gt;  The changes I needed to do is not changing code, but juggling dependencies to plugins and/or packages. Also creating a few platform-specific plugins (different based on whether I deploy on RCP or RAP).&lt;p /&gt;  It boils down to: &lt;ol type="1"&gt; &lt;li value="1" type="1"&gt;Do not hard-depend on &lt;b&gt;org.eclipse.ui&lt;/b&gt; plugin. Either depend on both &lt;b&gt;org.eclipse.ui&lt;/b&gt; and &lt;b&gt;org.eclipse.rap.ui&lt;/b&gt; plugins as optional dependencies, or import the specific packages. I prefer optional dependency on both plugins because it's much faster and easier. &lt;/li&gt;&lt;li value="2" type="1"&gt;Be aware that there will be multiple sessions at once. &lt;/li&gt;&lt;li value="3" type="1"&gt;2D Drawing functions are not yet fully available. (and I guess will never be available) &lt;/li&gt;&lt;/ol&gt; &lt;br /&gt; See the &lt;a href="http://wiki.eclipse.org/RAP/FAQ"&gt;Eclipse RAP FAQ on Single Sourcing&lt;/a&gt; for more information.   &lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href='http://posterous.com/getfile/files.posterous.com/eclipsedriven/YWALR7aaaGT7IjvfTsApEg8btwrUOT9pOXYWLXoxcgoEDEBL9elZM7sbT8yf/abispulsa-eclipse-rcp.png'&gt;&lt;img src="http://posterous.com/getfile/files.posterous.com/eclipsedriven/I7qJtdYO2zxD84MyLmWqaQ0PAYfT68m4UQyj2GBkky3fESmETnBapMJKRMHV/abispulsa-eclipse-rcp.png.scaled.500.jpg" width="500" height="380"/&gt;&lt;/a&gt; &lt;a href='http://posterous.com/getfile/files.posterous.com/eclipsedriven/LOpthfbJxYsm3k0YyYPupgHGwmfkKpQc6Z2L8guV6gGCHK9NS1kRBYbuf77S/abispulsa-eclipse-rap.png'&gt;&lt;img src="http://posterous.com/getfile/files.posterous.com/eclipsedriven/pxzigRmmROynH77Q3enooZNkOAWwjHeOpGzKnF0sde6MSufW3iLQjlvYoJ9n/abispulsa-eclipse-rap.png.scaled.500.jpg" width="500" height="321"/&gt;&lt;/a&gt; &lt;div&gt;&lt;a href='http://eclipsedriven.posterous.com/eclipse-rap-single-sourcing-awesomeness-with'&gt;See and download the full gallery on posterous&lt;/a&gt;&lt;/div&gt;&lt;/p&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/5843607076490024173/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/eclipse-rap-single-sourcing-awesomeness.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/5843607076490024173?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/5843607076490024173?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/eclipse-rap-single-sourcing-awesomeness.html" title="Eclipse RAP Single Sourcing Awesomeness (with EMF Editor and Teneo+Hibernate as bonus!)" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEYFRXk-fCp7ImA9Wx9RGE4.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-8276618274245496002</id><published>2010-12-20T00:01:00.001-08:00</published><updated>2010-12-20T00:01:54.754-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-20T00:01:54.754-08:00</app:edited><title>Fixing error: The type org.eclipse.core.runtime.IAdaptable cannot be resolved. It is indirectly referenced from required .class files.</title><content type="html">&lt;div class='posterous_autopost'&gt;      If you get one of the following errors :&lt;p /&gt;  &lt;tt&gt;The type org.eclipse.core.runtime.IAdaptable cannot be resolved. It is indirectly referenced from required .class files.&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;The type org.eclipse.core.runtime.CoreException cannot be resolved. It is indirectly referenced from required .class files.&lt;/tt&gt;&lt;p /&gt;  First of all, check that your plugins depend on &lt;b&gt;org.eclipse.core.runtime&lt;/b&gt; plugin.&lt;p /&gt;  The classes above are located in &lt;b&gt;org.eclipse.equinox.common&lt;/b&gt; plugin, and should be included (along with &lt;b&gt;org.eclipse.core.runtime&lt;/b&gt; plugin) in your target platform.&lt;p /&gt;  If it still occurs, most likely you get your target platform plugins mixed up. I got this error because I tried to mix plugins from my Eclipse IDE installation (Helios 3.6-SR-1) with Eclipse 3.7M4 Platform plugins.&lt;p /&gt;  Simply unchecking the plugins from target platform &lt;b&gt;Contents tab&lt;/b&gt; is not enough. I have to actually remove the location. If you notice duplicate plugins in your Target Platform Definition's Contents tab, then you're getting this problem.&lt;p /&gt;  Remove the offending plugins location from the target platform definition. If you must add plugins from Eclipse IDE location, cherry pick each plugin from the Locations UI, instead of just adding the whole SDK and unchecking them from the Contents tab.  &lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/8276618274245496002/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/fixing-error-type-orgeclipsecoreruntime.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/8276618274245496002?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/8276618274245496002?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/fixing-error-type-orgeclipsecoreruntime.html" title="Fixing error: The type org.eclipse.core.runtime.IAdaptable cannot be resolved. It is indirectly referenced from required .class files." /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUECRH89eCp7ImA9Wx9RF0U.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-1991741068717434801</id><published>2010-12-19T11:41:00.001-08:00</published><updated>2010-12-19T11:41:05.160-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-19T11:41:05.160-08:00</app:edited><title>Creating an About Dialog for your Eclipse RCP Application</title><content type="html">&lt;div class='posterous_autopost'&gt;&lt;a href='http://posterous.com/getfile/files.posterous.com/eclipsedriven/UYs3o5syMFwsMF6j5duDpq2Xu8ORq6NoJ7kFplcmMTcOuFwZB9DSZkxQuGXR/abispulsa-bisnis-rcp-about.png'&gt;&lt;img src="http://posterous.com/getfile/files.posterous.com/eclipsedriven/dImIKqBnCTvgWwblgqklpk7Lkk8uDOBfHr6noDt5ez44RrrKNFN0uVZaQr54/abispulsa-bisnis-rcp-about.png.scaled.500.jpg" width="500" height="219"/&gt;&lt;/a&gt; &lt;p&gt;      Displaying an &lt;b&gt;About box&lt;/b&gt; in your &lt;b&gt;Eclipse RCP Application/Product&lt;/b&gt; is actually very simple. However as is typical of a &lt;b&gt;framework&lt;/b&gt; (&amp;quot;don't call us, we'll call you&amp;quot; principle), there are conventions you must follow.&lt;p /&gt;  Before you do this, you must already create an &lt;b&gt;Eclipse RCP Application&lt;/b&gt; class that implements &lt;b&gt;IApplication&lt;/b&gt; and register it as an Eclipse extension in your &lt;tt&gt;plugin.xml&lt;/tt&gt;.&lt;p /&gt;  &lt;h3&gt; Adding the Help &amp;gt; About Menu Item &lt;/h3&gt; &lt;br /&gt; First, edit your ApplicationActionBarAdvisor class (which extends &lt;a href="http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/application/ActionBarAdvisor.html"&gt;org.eclipse.ui.application.ActionBarAdvisor&lt;/a&gt; base class), as follows:&lt;p /&gt;  &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected void makeActions(IWorkbenchWindow window) {&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; aboutAction = ActionFactory.ABOUT.create(window);&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; register(aboutAction);&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/tt&gt;&lt;p /&gt;  That will register the About action. You will also need to add the menu action itself to the menu bar:&lt;p /&gt;  &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected void fillMenuBar(IMenuManager menuBar) {&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MenuManager helpMenu = new MenuManager(&amp;quot;&amp;amp;Help&amp;quot;, IWorkbenchActionConstants.M_HELP);&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; menuBar.add(helpMenu);&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; helpMenu.add(aboutAction);&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/tt&gt;&lt;p /&gt;  Launch your Eclipse RCP application and you can display the About dialog.&lt;p /&gt;  &lt;h3&gt; Customizing the About Dialog Box &lt;/h3&gt; &lt;br /&gt; To customize the About dialog box's contents, first you must create an &lt;b&gt;Eclipse RCP Product Configuration&lt;/b&gt;.&lt;br /&gt; Click &lt;b&gt;File &amp;gt; New &amp;gt; Product Configuration&lt;/b&gt; and define your product.&lt;p /&gt;  This should also add your product to extension point '&lt;b&gt;org.eclipse.core.runtime.products&lt;/b&gt;'.&lt;p /&gt;  Edit your project's&lt;b&gt; Launch Configuration&lt;/b&gt; to use the your Product Configuration instead of Eclipse Application. Verify that it works well.&lt;p /&gt;  Now you can customize the About box contents by editing your Product Configuration (.product file), go to &lt;b&gt;Branding tab&lt;/b&gt; and &lt;b&gt;About Dialog&lt;/b&gt; section. Specify the About &lt;b&gt;Image&lt;/b&gt; and About &lt;b&gt;Text&lt;/b&gt; there.&lt;p /&gt;  To specify the image, import an image resource (PNG, GIF, JPG) to your plugin project (e.g. inside an &lt;b&gt;/icons&lt;/b&gt; folder). Important: Your image will need to be included inside your resulting plugin binary. Edit your plugin's manifest, go to Build tab, and make sure your images/icons are included (checked) for the &lt;b&gt;binary build&lt;/b&gt; and &lt;b&gt;source build&lt;/b&gt;.&lt;p /&gt;  After editing your Product Configuration, you &lt;b&gt;must&lt;/b&gt; synchronize it with the plugin manifest. Go to the Product's &lt;b&gt;Overview tab&lt;/b&gt; and click &lt;b&gt;Synchronize&lt;/b&gt; (under &lt;b&gt;Testing&lt;/b&gt;).&lt;p /&gt;  That action will update several properties in the &lt;b&gt;org.eclipse.core.runtime.products&lt;/b&gt; extension, for example:&lt;p /&gt;  &lt;tt&gt;&amp;nbsp;&amp;nbsp; &amp;lt;extension&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; id=&amp;quot;abispulsa_rcp&amp;quot;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; point=&amp;quot;org.eclipse.core.runtime.products&amp;quot;&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;product&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; application=&amp;quot;com.abispulsa.bisnis.rcp.application&amp;quot;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; description=&amp;quot;Layanan bagi korporasi untuk dapat dengan mudah mengisi pulsa.&amp;quot;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name=&amp;quot;AbisPulsa Bisnis RCP&amp;quot;&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name=&amp;quot;appName&amp;quot;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value=&amp;quot;AbisPulsa Bisnis RCP&amp;quot;&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/property&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name=&amp;quot;aboutText&amp;quot;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value=&amp;quot;AbisPulsa Bisnis merupakan layanan bagi korporasi untuk dapat dengan mudah mengisi pulsa.&amp;quot;&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/property&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name=&amp;quot;aboutImage&amp;quot;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value=&amp;quot;icons/AbisPulsa_icon_75x75.png&amp;quot;&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/property&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/product&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/extension&amp;gt;&lt;/tt&gt;&lt;p /&gt;  For your information: Other properties you can use include: &lt;ul&gt; &lt;li&gt;windowImages &lt;/li&gt;&lt;li&gt;&lt;b&gt;aboutImage&lt;/b&gt; &lt;/li&gt;&lt;li&gt;&lt;b&gt;aboutText&lt;/b&gt; &lt;/li&gt;&lt;li&gt;appName &lt;/li&gt;&lt;li&gt;welcomePage &lt;/li&gt;&lt;li&gt;preferenceCustomization &lt;/li&gt;&lt;/ul&gt; &lt;br /&gt; References: &lt;ol type="1"&gt; &lt;li value="1" type="1"&gt;&lt;a href="http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/product_def_extpt.htm"&gt;http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/product_def_extpt.htm&lt;/a&gt; &lt;/li&gt;&lt;li value="2" type="1"&gt;&lt;a href="http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/extension-points/org_eclipse_core_runtime_products.html"&gt;http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/extension-points/org_eclipse_core_runtime_products.html&lt;/a&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;/p&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/1991741068717434801/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/creating-about-dialog-for-your-eclipse.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/1991741068717434801?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/1991741068717434801?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/creating-about-dialog-for-your-eclipse.html" title="Creating an About Dialog for your Eclipse RCP Application" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0QCR3c9fCp7ImA9Wx9RF0U.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-4879129616197723973</id><published>2010-12-19T09:56:00.001-08:00</published><updated>2010-12-19T09:56:06.964-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-19T09:56:06.964-08:00</app:edited><title>Fixing Eclipse RCP Launch Error: Application "org.eclipse.ui.ide.workbench" could not be found in the registry.</title><content type="html">&lt;div class='posterous_autopost'&gt;      If you encounter the following error message when launching your &lt;b&gt;Eclipse RCP application/plugin&lt;/b&gt; :&lt;p /&gt;  &lt;tt&gt;!ENTRY org.eclipse.osgi 4 0 2010-12-20 00:49:08.433&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;!MESSAGE Application error&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;!STACK 1&lt;/tt&gt;&lt;br /&gt; &lt;b&gt;&lt;tt&gt;java.lang.RuntimeException: Application &amp;quot;org.eclipse.ui.ide.workbench&amp;quot; could not be found in the registry. The applications available are&lt;/tt&gt;&lt;tt&gt;: org.eclipse.ant.core.antRunner, org.eclipse.jdt.core.JavaCodeFormatter, org.eclipse.help.base.infocenterApplication, org.eclipse.help.base.helpApplication, org.eclipse.help.base.indexTool, com.abispulsa.bisnis.rcp.application, org.eclipse.equinox.app.error.&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at org.eclipse.equinox.internal.app.EclipseAppContainer.startDefaultApp(EclipseAppContainer.java:248)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at org.eclipse.equinox.internal.app.MainApplicationLauncher.run(MainApplicationLauncher.java:29)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at java.lang.reflect.Method.invoke(Method.java:597)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at org.eclipse.equinox.launcher.Main.run(Main.java:1407)&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;	at org.eclipse.equinox.launcher.Main.main(Main.java:1383)&lt;/tt&gt;&lt;p /&gt;  It means that you haven't added the following plugin to your &lt;b&gt;target platform / enabled plugins&lt;/b&gt;:&lt;p /&gt;  &lt;b&gt;&lt;tt&gt;org.eclipse.ui.ide.application&lt;/tt&gt;&lt;p /&gt;  That means you'll use the default &amp;quot;workbench&amp;quot; application as used by Eclipse IDE.&lt;p /&gt;  When you've created your own application class which implements &lt;a href="http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/api/org/eclipse/equinox/app/IApplication.html"&gt;org.eclipse.equinox.app.IApplication interface&lt;/a&gt;, you need to register an Eclipse extension to &lt;tt&gt;&lt;b&gt;org.eclipse.core.runtime.applications&lt;/b&gt;&lt;/tt&gt; in your &lt;tt&gt;&lt;b&gt;plugin.xml&lt;/b&gt;&lt;/tt&gt; like the following example:&lt;p /&gt;  &lt;tt&gt;&amp;nbsp;&amp;nbsp; &amp;lt;extension id=&amp;quot;application&amp;quot;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; point=&amp;quot;org.eclipse.core.runtime.applications&amp;quot;&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;application&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;run class=&amp;quot;com.abispulsa.bisnis.rcp.Application&amp;quot;&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/run&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/application&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/extension&amp;gt;&lt;/tt&gt;&lt;p /&gt;  Then edit your &lt;b&gt;Eclipse Application launch configuration&lt;/b&gt; to use your own application class.  &lt;/b&gt;&lt;/b&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/4879129616197723973/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/fixing-eclipse-rcp-launch-error.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/4879129616197723973?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/4879129616197723973?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/fixing-eclipse-rcp-launch-error.html" title="Fixing Eclipse RCP Launch Error: Application &amp;quot;org.eclipse.ui.ide.workbench&amp;quot; could not be found in the registry." /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkYNSHk7fCp7ImA9Wx9RF0s.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-5403334504163321550</id><published>2010-12-19T05:09:00.003-08:00</published><updated>2010-12-19T05:09:59.704-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-19T05:09:59.704-08:00</app:edited><title>Mirroring an Eclipse Update Site to a Local p2 Repository</title><content type="html">&lt;div class='posterous_autopost'&gt;      &lt;b&gt;Installing&lt;/b&gt; or &lt;b&gt;updating Eclipse plugins/features&lt;/b&gt; is easy using &lt;b&gt;Eclipse p2 Update Sites&lt;/b&gt;. However, since it requires downloading from the Internet the process is often very slow.&lt;p /&gt;  Some projects provide an &lt;b&gt;archived update site&lt;/b&gt; (&lt;b&gt;.zip&lt;/b&gt; file) but the rest do not provide them. When installing or updating features for multiple Eclipse IDE or RCP Application installations, downloading the same files multiple times from the Internet can get annoying. Not to mention it definitely wastes precious time AND bandwidth.&lt;p /&gt;  Thankfully there is a way to create a &lt;b&gt;local p2 repository&lt;/b&gt; that acts as a &lt;b&gt;mirror site&lt;/b&gt; to the original &lt;b&gt;Eclipse p2 Update Sites&lt;/b&gt;.&lt;p /&gt;  This is useful for making available a full Eclipse release or a set of Eclipse features/plugins to internal corporate users, for example, reducing the bandwidth normally used with dozens of users downloading the same bits from external Eclipse p2 Update sites.&lt;p /&gt;  &lt;h3&gt; Documentation &lt;/h3&gt; &lt;br /&gt; First, you need to mirror the site (or a particular feature), so take a look at the mirror command described here:&lt;br /&gt; &lt;a href="http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/misc/update_standalone.html"&gt;Running Update Manager from Command Line&lt;/a&gt;&lt;p /&gt;  then create a site policy (a type of redirection) as described here:&lt;br /&gt; &lt;a href="http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.user/tasks/tasks-37.htm"&gt;Controlling the Eclipse Update Policy&lt;/a&gt;&lt;p /&gt;  &lt;h3&gt; Command Examples &lt;/h3&gt; &lt;br /&gt; You can start the update manager in a standalone mode to create a mirror of an update site by using&lt;br /&gt; this command:&lt;p /&gt;  &lt;tt&gt;java -Dhttp.proxyHost=yourProxy -Dhttp.proxyPort=yourProxyPort \&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; -jar plugins/org.eclipse.equinox.launcher_&amp;lt;version&amp;gt;.jar \&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; -application org.eclipse.update.core.standaloneUpdate -command mirror \&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; -from %updateSiteToMirror% -mirrorUrl %urlOfYourUpdateSite% \&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; -to %fileLocationToMirrorTo%&lt;/tt&gt;&lt;p /&gt;  Run this command from Eclipse install directory (i.e. where startup.jar is). &lt;br /&gt; Replace %fileLocationToMirrorTo% with the local directory where the update site contents will be copied to, and %urlOfYourUpdateSite% with a URL which will point to the directory you informed.&lt;p /&gt;  Of course you will need to install a local web server, like &lt;a href="http://httpd.apache.org"&gt;Apache HTTPD&lt;/a&gt; and configure it according the directory/URL you specified before.&lt;p /&gt;  It even supports to create one mirror-site of multiple sites if you specify the same location for multiple sites it will append them to the site.xml giving you one big (and messy) update site.&lt;p /&gt;  An easy way to use this is use a dos or bash scipt ofcourse. For example the following script to mirror the relevant update sites:&lt;p /&gt;  &lt;tt&gt;set LAUNCHER=C:\opt\springsource-2.1\sts-2.1.0.RELEASE\plugins/plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;call updateSite &lt;a href="http://subclipse.tigris.org/update_1.6.x"&gt;http://subclipse.tigris.org/update_1.6.x&lt;/a&gt; subclipse&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://pmd.sourceforge.net/eclipse"&gt;http://pmd.sourceforge.net/eclipse&lt;/a&gt; pmd&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://m2eclipse.sonatype.org/update/"&gt;http://m2eclipse.sonatype.org/update/&lt;/a&gt; m2eclipse&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://findbugs.cs.umd.edu/eclipse/&amp;amp;nbsp;"&gt;http://findbugs.cs.umd.edu/eclipse/&amp;nbsp;&lt;/a&gt; findbugs&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://moreunit.sourceforge.net/org.moreunit.updatesite/&amp;amp;nbsp;"&gt;http://moreunit.sourceforge.net/org.moreunit.updatesite/&amp;nbsp;&lt;/a&gt; moreunit&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://www.springsource.com/update/e3.5"&gt;http://www.springsource.com/update/e3.5&lt;/a&gt; sprinsource-e35&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://eclipse-cs.sf.net/update"&gt;http://eclipse-cs.sf.net/update&lt;/a&gt; checkstyle&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://update.atlassian.com/atlassian-eclipse-plugin"&gt;http://update.atlassian.com/atlassian-eclipse-plugin&lt;/a&gt; atlassian&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://commonclipse.sourceforge.net"&gt;http://commonclipse.sourceforge.net&lt;/a&gt; commonclipse&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="https://ajax.dev.java.net/eclipse"&gt;https://ajax.dev.java.net/eclipse&lt;/a&gt; glassfish&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://andrei.gmxhome.de/eclipse/"&gt;http://andrei.gmxhome.de/eclipse/&lt;/a&gt; gmx-plugins&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://regex-util.sourceforge.net/update/"&gt;http://regex-util.sourceforge.net/update/&lt;/a&gt; regex&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://ucdetector.sourceforge.net/update/"&gt;http://ucdetector.sourceforge.net/update/&lt;/a&gt; ucdetector&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;goto:eof&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;:updateSite&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;java -Dhttp.proxyHost=yourProxy	-Dhttp.proxyPort=yourProxyPort -jar %LAUNCHER% -application org.eclipse.update.core.standaloneUpdate -command mirror -from %1 -mirrorUrl &lt;a href="http://server/eclipseupdatesite/%2"&gt;http://server/eclipseupdatesite/%2&lt;/a&gt; -to Y:\%2 &amp;amp;goto:eof&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;goto:eof&lt;/tt&gt; &lt;br /&gt; This gives us multiple update sites under http://server/eclipseupdatesite/ like http://server/eclipseupdatesite/m2eclipse etc. Of course you still need 1 computer to have unrestricted/fast internet access, but you can always create those sites at home.&lt;p /&gt;  &lt;h3&gt; Aggregating Specific Features &lt;/h3&gt; You can also aggregate several features from other update sites to your own, using either &lt;b&gt;&lt;a href="http://wiki.eclipse.org/Equinox/p2/Ant_Tasks"&gt;p2.mirror&lt;/a&gt;&lt;/b&gt;, &lt;b&gt;&lt;a href="http://wiki.eclipse.org/Equinox/p2/Composite_Repositories_%28new%29"&gt;p2 Composite Repositories&lt;/a&gt;&lt;/b&gt;, &lt;b&gt;&lt;a href="http://wiki.eclipse.org/Eclipse_b3/aggregator/manual"&gt;b3&lt;/a&gt;&lt;/b&gt;, or &lt;b&gt;&lt;a href="http://www.sonatype.com/nexus-professional.html"&gt;Nexus Pro&lt;/a&gt;&lt;/b&gt;.&lt;p /&gt;  See &lt;a href="http://stackoverflow.com/questions/4378112/p2-repositories-aggregator"&gt;http://stackoverflow.com/questions/4378112/p2-repositories-aggregator&lt;/a&gt;&lt;p /&gt;  &lt;br /&gt; Sources: &lt;ol type="1"&gt; &lt;li value="1" type="1"&gt;&lt;a href="http://dev.eclipse.org/newslists/news.eclipse.platform/msg29529.html"&gt;http://dev.eclipse.org/newslists/news.eclipse.platform/msg29529.html&lt;/a&gt; &lt;/li&gt;&lt;li value="2" type="1"&gt;&lt;a href="http://stackoverflow.com/questions/4378112/p2-repositories-aggregator"&gt;http://stackoverflow.com/questions/4378112/p2-repositories-aggregator&lt;/a&gt; &lt;/li&gt;&lt;li value="3" type="1"&gt;&lt;a href="http://www.willianmitsuda.com/2007/03/09/mirroring-callisto-update-site/"&gt;http://www.willianmitsuda.com/2007/03/09/mirroring-callisto-update-site/&lt;/a&gt; &lt;/li&gt;&lt;li value="4" type="1"&gt;&lt;a href="http://www.denoo.info/2009/09/mirroring-eclipse-update-sites/"&gt;http://www.denoo.info/2009/09/mirroring-eclipse-update-sites/&lt;/a&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/5403334504163321550/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/mirroring-eclipse-update-site-to-local_19.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/5403334504163321550?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/5403334504163321550?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/mirroring-eclipse-update-site-to-local_19.html" title="Mirroring an Eclipse Update Site to a Local p2 Repository" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkYNQHg_eyp7ImA9Wx9RF0s.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-8355270861241007229</id><published>2010-12-19T05:09:00.001-08:00</published><updated>2010-12-19T05:09:51.643-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-19T05:09:51.643-08:00</app:edited><title>Mirroring an Eclipse Update Site to a Local p2 Repository</title><content type="html">&lt;div class='posterous_autopost'&gt;      &lt;b&gt;Installing&lt;/b&gt; or &lt;b&gt;updating Eclipse plugins/features&lt;/b&gt; is easy using &lt;b&gt;Eclipse p2 Update Sites&lt;/b&gt;. However, since it requires downloading from the Internet the process is often very slow.&lt;p /&gt;  Some projects provide an &lt;b&gt;archived update site&lt;/b&gt; (&lt;b&gt;.zip&lt;/b&gt; file) but the rest do not provide them. When installing or updating features for multiple Eclipse IDE or RCP Application installations, downloading the same files multiple times from the Internet can get annoying. Not to mention it definitely wastes precious time AND bandwidth.&lt;p /&gt;  Thankfully there is a way to create a &lt;b&gt;local p2 repository&lt;/b&gt; that acts as a &lt;b&gt;mirror site&lt;/b&gt; to the original &lt;b&gt;Eclipse p2 Update Sites&lt;/b&gt;.&lt;p /&gt;  This is useful for making available a full Eclipse release or a set of Eclipse features/plugins to internal corporate users, for example, reducing the bandwidth normally used with dozens of users downloading the same bits from external Eclipse p2 Update sites.&lt;p /&gt;  &lt;h3&gt; Documentation &lt;/h3&gt; &lt;br /&gt; First, you need to mirror the site (or a particular feature), so take a look at the mirror command described here:&lt;br /&gt; &lt;a href="http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/misc/update_standalone.html"&gt;Running Update Manager from Command Line&lt;/a&gt;&lt;p /&gt;  then create a site policy (a type of redirection) as described here:&lt;br /&gt; &lt;a href="http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.user/tasks/tasks-37.htm"&gt;Controlling the Eclipse Update Policy&lt;/a&gt;&lt;p /&gt;  &lt;h3&gt; Command Examples &lt;/h3&gt; &lt;br /&gt; You can start the update manager in a standalone mode to create a mirror of an update site by using&lt;br /&gt; this command:&lt;p /&gt;  &lt;tt&gt;java -Dhttp.proxyHost=yourProxy -Dhttp.proxyPort=yourProxyPort \&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; -jar plugins/org.eclipse.equinox.launcher_&amp;lt;version&amp;gt;.jar \&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; -application org.eclipse.update.core.standaloneUpdate -command mirror \&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; -from %updateSiteToMirror% -mirrorUrl %urlOfYourUpdateSite% \&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp; -to %fileLocationToMirrorTo%&lt;/tt&gt;&lt;p /&gt;  Run this command from Eclipse install directory (i.e. where startup.jar is). &lt;br /&gt; Replace %fileLocationToMirrorTo% with the local directory where the update site contents will be copied to, and %urlOfYourUpdateSite% with a URL which will point to the directory you informed.&lt;p /&gt;  Of course you will need to install a local web server, like &lt;a href="http://httpd.apache.org"&gt;Apache HTTPD&lt;/a&gt; and configure it according the directory/URL you specified before.&lt;p /&gt;  It even supports to create one mirror-site of multiple sites if you specify the same location for multiple sites it will append them to the site.xml giving you one big (and messy) update site.&lt;p /&gt;  An easy way to use this is use a dos or bash scipt ofcourse. For example the following script to mirror the relevant update sites:&lt;p /&gt;  &lt;tt&gt;set LAUNCHER=C:\opt\springsource-2.1\sts-2.1.0.RELEASE\plugins/plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;call updateSite &lt;a href="http://subclipse.tigris.org/update_1.6.x"&gt;http://subclipse.tigris.org/update_1.6.x&lt;/a&gt; subclipse&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://pmd.sourceforge.net/eclipse"&gt;http://pmd.sourceforge.net/eclipse&lt;/a&gt; pmd&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://m2eclipse.sonatype.org/update/"&gt;http://m2eclipse.sonatype.org/update/&lt;/a&gt; m2eclipse&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://findbugs.cs.umd.edu/eclipse/&amp;amp;nbsp;"&gt;http://findbugs.cs.umd.edu/eclipse/&amp;nbsp;&lt;/a&gt; findbugs&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://moreunit.sourceforge.net/org.moreunit.updatesite/&amp;amp;nbsp;"&gt;http://moreunit.sourceforge.net/org.moreunit.updatesite/&amp;nbsp;&lt;/a&gt; moreunit&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://www.springsource.com/update/e3.5"&gt;http://www.springsource.com/update/e3.5&lt;/a&gt; sprinsource-e35&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://eclipse-cs.sf.net/update"&gt;http://eclipse-cs.sf.net/update&lt;/a&gt; checkstyle&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://update.atlassian.com/atlassian-eclipse-plugin"&gt;http://update.atlassian.com/atlassian-eclipse-plugin&lt;/a&gt; atlassian&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://commonclipse.sourceforge.net"&gt;http://commonclipse.sourceforge.net&lt;/a&gt; commonclipse&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="https://ajax.dev.java.net/eclipse"&gt;https://ajax.dev.java.net/eclipse&lt;/a&gt; glassfish&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://andrei.gmxhome.de/eclipse/"&gt;http://andrei.gmxhome.de/eclipse/&lt;/a&gt; gmx-plugins&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://regex-util.sourceforge.net/update/"&gt;http://regex-util.sourceforge.net/update/&lt;/a&gt; regex&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;call updateSite &lt;a href="http://ucdetector.sourceforge.net/update/"&gt;http://ucdetector.sourceforge.net/update/&lt;/a&gt; ucdetector&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;goto:eof&lt;/tt&gt;&lt;p /&gt;  &lt;tt&gt;:updateSite&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;java -Dhttp.proxyHost=yourProxy	-Dhttp.proxyPort=yourProxyPort -jar %LAUNCHER% -application org.eclipse.update.core.standaloneUpdate -command mirror -from %1 -mirrorUrl &lt;a href="http://server/eclipseupdatesite/%2"&gt;http://server/eclipseupdatesite/%2&lt;/a&gt; -to Y:\%2 &amp;amp;goto:eof&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;goto:eof&lt;/tt&gt; &lt;br /&gt; This gives us multiple update sites under http://server/eclipseupdatesite/ like http://server/eclipseupdatesite/m2eclipse etc. Of course you still need 1 computer to have unrestricted/fast internet access, but you can always create those sites at home.&lt;p /&gt;  &lt;h3&gt; Aggregating Specific Features &lt;/h3&gt; You can also aggregate several features from other update sites to your own, using either &lt;b&gt;&lt;a href="http://wiki.eclipse.org/Equinox/p2/Ant_Tasks"&gt;p2.mirror&lt;/a&gt;&lt;/b&gt;, &lt;b&gt;&lt;a href="http://wiki.eclipse.org/Equinox/p2/Composite_Repositories_%28new%29"&gt;p2 Composite Repositories&lt;/a&gt;&lt;/b&gt;, &lt;b&gt;&lt;a href="http://wiki.eclipse.org/Eclipse_b3/aggregator/manual"&gt;b3&lt;/a&gt;&lt;/b&gt;, or &lt;b&gt;&lt;a href="http://www.sonatype.com/nexus-professional.html"&gt;Nexus Pro&lt;/a&gt;&lt;/b&gt;.&lt;p /&gt;  See &lt;a href="http://stackoverflow.com/questions/4378112/p2-repositories-aggregator"&gt;http://stackoverflow.com/questions/4378112/p2-repositories-aggregator&lt;/a&gt;&lt;p /&gt;  &lt;br /&gt; Sources: &lt;ol type="1"&gt; &lt;li value="1" type="1"&gt;&lt;a href="http://dev.eclipse.org/newslists/news.eclipse.platform/msg29529.html"&gt;http://dev.eclipse.org/newslists/news.eclipse.platform/msg29529.html&lt;/a&gt; &lt;/li&gt;&lt;li value="2" type="1"&gt;&lt;a href="http://stackoverflow.com/questions/4378112/p2-repositories-aggregator"&gt;http://stackoverflow.com/questions/4378112/p2-repositories-aggregator&lt;/a&gt; &lt;/li&gt;&lt;li value="3" type="1"&gt;&lt;a href="http://www.willianmitsuda.com/2007/03/09/mirroring-callisto-update-site/"&gt;http://www.willianmitsuda.com/2007/03/09/mirroring-callisto-update-site/&lt;/a&gt; &lt;/li&gt;&lt;li value="4" type="1"&gt;&lt;a href="http://www.denoo.info/2009/09/mirroring-eclipse-update-sites/"&gt;http://www.denoo.info/2009/09/mirroring-eclipse-update-sites/&lt;/a&gt; &lt;/li&gt;&lt;/ol&gt;  &lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/8355270861241007229/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/mirroring-eclipse-update-site-to-local.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/8355270861241007229?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/8355270861241007229?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/mirroring-eclipse-update-site-to-local.html" title="Mirroring an Eclipse Update Site to a Local p2 Repository" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D08NSXs4fCp7ImA9Wx9RF0g.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-5102989951547746450</id><published>2010-12-19T02:51:00.001-08:00</published><updated>2010-12-19T02:51:38.534-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-19T02:51:38.534-08:00</app:edited><title>Making Software Literate: The Parser, The Interpreter, and The Literal</title><content type="html">&lt;div class='posterous_autopost'&gt;In my last post, the title suggests "teaching code to read itself". However all I wrote was about Interpreter. &lt;p /&gt; For code to read itself, it must be able to generate a model from itself. Therefore, you need the metamodel of the programming lanaguage the software is written in, and the grammar of that language. By using those two ingredients and the proper tools, you can generate a model from the software. &lt;p /&gt; An example of a comprehensive tool for doing this is Eclipse MoDisco. It comes with a complete tooling for discovering / reflecting / introspecting a Java project. &lt;p /&gt; However, for software to understand the model, it must also have an Interpreter/Evaluator, which can do something with the model. &lt;p /&gt; In a way, a generator is a specialized kind of interpreter which simply outputs the concrete representation ("artifact") of the model being processed. &lt;p /&gt; To not only read a model but also to make changes to it, we need a Manipulator (what a scary name), which is a kind of interpreter that performs actions on a model. Sample action: delete an EClass node named 'Car'. &lt;p /&gt; After making changes, the resulting model can be generated back to file artifacts using generator. The project can then be rebuilt, only the changed artifacts are needed. &lt;p /&gt; To rebuild the project from scratch though, we need a complete set of project files. &lt;p /&gt; A typical software project, not only consists of a single language (hence metamodel) but several other artifacts including: &lt;br /&gt;- build.xml (Ant build) &lt;br /&gt;- plugin.xml, MANIFEST.MF (PDE project) &lt;br /&gt;- pom.xml (Maven project) &lt;br /&gt;- build.gradle (Gradle build) &lt;br /&gt;- .project, .classpath, build.properties (Eclipse JDT project) &lt;p /&gt; Depending on requirements, it may not be needed (sometimes not even desirable) to model all of those artifacts properly. Sometimes, it's enough to model a file as a 'Literal': &lt;p /&gt; File: EClass &lt;br /&gt;----------------------- &lt;br /&gt;name: EString &lt;br /&gt;directory: EString &lt;br /&gt;contents: EString &lt;p /&gt; Which in practice means, that these artifacts are not part of the model-driven lifecycle at all. (i.e. You can actually ignore it and it won't evenmatter) &lt;p /&gt; Model-driven is all about transformation, or processing, or shapeshifting, or (meta)morphing. If an artifact or model stays the same throughout the lifecycle, and it's not being used as a metamodel for transformation of its instances, then it's the same thing as if modeling is not used at all. &lt;p /&gt; When all project artifacts are understood, 'literalled', or generated, the project can be rebuilt from scratch using the model. With a good headless build system such as Maven or Gradle, this should be simple. &lt;p /&gt; The other part to include is the information "in programmer's head". We deal with this everyday that it seldom occurs to us that it *is* information. &lt;p /&gt; Things like: &lt;br /&gt;- the directory location of the project &lt;br /&gt;- project name &lt;br /&gt;- location and name of the generated binaries &lt;br /&gt;- SCM user, password, URL &lt;br /&gt;- SCM tool &lt;br /&gt;- test status (whether the tests pass, how many tests, how many fails, how many passes) &lt;p /&gt; These information should be modeled, and a specialized interpreter can be created to act on the project. &lt;p /&gt; A final behavior is 'replaceSelf', which requires the following information: &lt;br /&gt;1. self source location &lt;br /&gt;2. self binary location &lt;br /&gt;3. self descriptor model &lt;br /&gt;4. location of *this* self descriptor model &lt;br /&gt;5. prototype source location &lt;br /&gt;6. prototype binary location &lt;br /&gt;7. prototype descriptor model &lt;p /&gt; where 'prototype' is the project that we've discussed and built above. &lt;p /&gt; The replaceSelf behavior, given the 'self descriptor model' will update/replace itself using the prototype locations, and also update the self descriptor model (e.g. Update the version number). &lt;p /&gt; If the software runs continuously (as a server/daemon), it can then fork a new version of itself, then terminate its own instance. &lt;p /&gt; I guess now the lifecycle is complete. ;-)&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/5102989951547746450/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/making-software-literate-parser.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/5102989951547746450?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/5102989951547746450?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/making-software-literate-parser.html" title="Making Software Literate: The Parser, The Interpreter, and The Literal" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEEFRns9cSp7ImA9Wx9RF0g.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-8347629564003441416</id><published>2010-12-19T01:56:00.001-08:00</published><updated>2010-12-19T01:56:57.569-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-19T01:56:57.569-08:00</app:edited><title>Making Software Literate: Teaching Code to Read Itself</title><content type="html">&lt;div class='posterous_autopost'&gt;My previous post introduces the concept of Grammar, Template, and the Metamodel. &lt;p /&gt; Creating metamodel is easy for humans, there is Ecore editor and Ecore Tools for that. &lt;p /&gt; Generating artifacts from a model is also relatively easier... When compared to "reading" artifacts and generating a model. &lt;p /&gt; In the machine world, almost everything is harder to read than to write. &lt;p /&gt; For example, it is easy for a generator to output this: &lt;p /&gt; lastName = "Irawan" &lt;br /&gt;name = "Hendy " + lastName &lt;p /&gt; However, it's not easy to "read" the above artifact. By that I mean that the parser software should "understand" that 'name' contains "Hendy Irawan". &lt;p /&gt; And it brings us to... Interpreter. &lt;p /&gt; Interpreter is an enhanced parser that knows what to do with a model. Advanced interpreters may have behaviors, but the most commonly used functionality is Evaluating Expressions. &lt;p /&gt; An Evaluator transforms expressions in the metamodel to actual values (which are still expressions, called value expression, but do not need further processing). After the example artifact above are parsed AND interpreted/evaluated, the 'name' object will rightly contain 'Hendy Irawan'.&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/8347629564003441416/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/making-software-literate-teaching-code.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/8347629564003441416?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/8347629564003441416?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/making-software-literate-teaching-code.html" title="Making Software Literate: Teaching Code to Read Itself" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0QBQnw_eip7ImA9Wx9RF0g.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-3446164379278411444</id><published>2010-12-19T01:35:00.001-08:00</published><updated>2010-12-19T01:35:53.242-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-19T01:35:53.242-08:00</app:edited><title>Grammar and Template's Role in Modeling</title><content type="html">&lt;div class='posterous_autopost'&gt;Grammar and Template are two essential components for model-driven reflection and generation. &lt;p /&gt; Note that this article relates to high-level, abstract view of Model Driven Engineering. And it's going to be boring and theoretical, but I have to write it down so I won't forget. ;-) &lt;p /&gt; With a Grammar, you can 'read' or understand or introspect or reflect or parse or deconstruct or reverse-engineer or (in a way) deserialize... from a concrete artifact, and generating a model as an output. &lt;p /&gt; With a Template, you can 'write' or generate or create or build or construct or (in a way) serialize... an artifact as an output, from a model. &lt;p /&gt; The third element which is required by both processes, is the metamodel. It's actually a prerequirement. &lt;p /&gt; These three are the core ingredients for model driven engineering. &lt;p /&gt; Now to actually bake these ingredients, you need equipment, the tools. Fortunately these are all provided by Eclipse Modeling Framework projects. &lt;p /&gt; The first ingredient you need to create is the metamodel, which usually means an Ecore model. In later phases, the metamodel is not always the first artifact, it can be a generated artifact. &lt;p /&gt; To read an artifact, you need a tool, the parser, that can read your metamodel. And create a grammar in a language that the tool understands. An example is Xtext with its Xtext grammar language. And Xtext, of course, understands Ecore models as the metamodel. &lt;p /&gt; Given: metamodel + grammar --&gt; Xtext, you will get a Parser. &lt;p /&gt; A parser is an artifact reader that is customized to your grammar and metamodel. Given concrete artifact(s) as input, it generates a model as output. &lt;p /&gt; To write to an artifact, you need a tool, that is a generator, that can read your metamodel. Then you create a template in a language that the generator understands. &lt;p /&gt; Such a generator is Eclipse M2T Xpand, and its Xpand language. &lt;p /&gt; Given metamodel + model + template --&gt; Xpand, you get: (textual) artifact! &lt;p /&gt; Actually, the concrete examples above assume one thing: the other metamodel (the "artifact") is a filesystem with text files. &lt;p /&gt; In an abstract way, all transformations are model-to-model (M2M) transformations, hence conceptually requiring two metamodels, not just one. M2T (generation) and T2M (parsing) are conceptually M2M where one side is textual files, or "textual metamodel".&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/3446164379278411444/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/grammar-and-template-role-in-modeling.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/3446164379278411444?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/3446164379278411444?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/grammar-and-template-role-in-modeling.html" title="Grammar and Template&amp;#39;s Role in Modeling" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUIGRH0ycCp7ImA9Wx9RF0k.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-3417141968132965037</id><published>2010-12-19T00:32:00.001-08:00</published><updated>2010-12-19T00:32:05.398-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-19T00:32:05.398-08:00</app:edited><title>In order for code to understand itself, it must be able to generate a model from its own code.</title><content type="html">&lt;div class='posterous_autopost'&gt;In order for code to understand itself, it must be able to generate a model (reverse engineer / discover / import) from its own code. &lt;p /&gt; Its model can then be used to generate code and build it, thus understanding and building itself.&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/3417141968132965037/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/in-order-for-code-to-understand-itself.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/3417141968132965037?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/3417141968132965037?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/in-order-for-code-to-understand-itself.html" title="In order for code to understand itself, it must be able to generate a model from its own code." /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DE4BQHo_fSp7ImA9Wx9RF00.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-1322368526115967914</id><published>2010-12-18T13:15:00.001-08:00</published><updated>2010-12-18T13:15:51.445-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-18T13:15:51.445-08:00</app:edited><title>What You Need to Start Model-to-Text Transformation with Xpand</title><content type="html">&lt;div class='posterous_autopost'&gt;      Setup your &lt;b&gt;Model-driven Development Environment&lt;/b&gt;: &lt;ol type="1"&gt; &lt;li value="1" type="1"&gt;Get &lt;b&gt;&lt;a href="http://eclipse.org/downloads/"&gt;Eclipse IDE&lt;/a&gt;, Modeling&lt;/b&gt; distribution. &lt;/li&gt;&lt;li value="2" type="1"&gt;Install &lt;b&gt;&lt;a href="http://www.eclipse.org/modeling/m2t/?project=xpand"&gt;Xpand&lt;/a&gt;&lt;/b&gt; to Eclipse IDE &lt;/li&gt;&lt;li value="3" type="1"&gt;Install &lt;b&gt;&lt;a href="http://www.eclipse.org/modeling/emft/?project=mwe"&gt;MWE&lt;/a&gt;&lt;/b&gt; to Eclipse IDE &lt;/li&gt;&lt;li value="4" type="1"&gt;&lt;b&gt;&lt;a href="http://wiki.eclipse.org/index.php/Ecore_Tools"&gt;Ecore Tools&lt;/a&gt;&lt;/b&gt; is optional, but it helps you to create your metamodel (Ecore model) using a nicer visual diagram editor. &lt;/li&gt;&lt;/ol&gt; &lt;br /&gt; Now you can create your project: &lt;ol type="1"&gt; &lt;li value="1" type="1"&gt;Create your metamodel (.ecore file). Better just use Ecore Tools, and create .ecorediag diagram alongside .ecore file. &lt;/li&gt;&lt;li value="2" type="1"&gt;Create a .genmodel from your metamodel. &lt;/li&gt;&lt;li value="3" type="1"&gt;Generate your Model package and classes from the .genmodel. &lt;/li&gt;&lt;li value="4" type="1"&gt;Create a sample model (instance). &lt;/li&gt;&lt;li value="5" type="1"&gt;Open the .ecore model file, right click on a EClass and choose &lt;b&gt;Create Dynamic Instance&lt;/b&gt;. &lt;/li&gt;&lt;li value="6" type="1"&gt;Create a Xpand template. &lt;/li&gt;&lt;li value="7" type="1"&gt;Create a MWE workflow file (.mwe). &lt;/li&gt;&lt;li value="8" type="1"&gt;Add necessary plugin dependencies to the MANIFEST.MF. &lt;/li&gt;&lt;/ol&gt; Now you can run the workflow.&lt;p /&gt;  The steps above the high-level steps. It sounds complicated and indeed it can be confusing at first. (the reason why I'm blogging this here is so that I won't get confused in the future) ;-)&lt;p /&gt;  If you want the simplest thing, use the &lt;b&gt;New Xpand Project Wizard - Sample Xpand Project&lt;/b&gt; and it'll provide up a ready-to-use &lt;b&gt;Ecore+Xpand+MWE&amp;nbsp; setup&lt;/b&gt; for you. :-)&lt;p /&gt;  Note: MWE and Xpand package names has changed since moved from &lt;b&gt;openArchitectureWare&lt;/b&gt; to &lt;b&gt;Eclipse Modeling Framework&lt;/b&gt; umbrella, so be aware of this when following older tutorials.  &lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/1322368526115967914/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/what-you-need-to-start-model-to-text.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/1322368526115967914?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/1322368526115967914?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/what-you-need-to-start-model-to-text.html" title="What You Need to Start Model-to-Text Transformation with Xpand" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;Dk4BRH06fyp7ImA9Wx9RF00.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-3140968869349828376</id><published>2010-12-18T12:42:00.001-08:00</published><updated>2010-12-18T12:42:35.317-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-18T12:42:35.317-08:00</app:edited><title>How to Solve MWE/Xpand Workflow Problems/Errors</title><content type="html">&lt;div class='posterous_autopost'&gt;      &lt;b&gt;What to Check :&lt;/b&gt;&lt;p /&gt;  1. Check your model file (&lt;b&gt;.xmi&lt;/b&gt;). See: &lt;a href="http://spring-java-ee.blogspot.com/2010/12/fixing-eclipse-mwe-error-workflow.html"&gt;http://spring-java-ee.blogspot.com/2010/12/fixing-eclipse-mwe-error-workflow.html&lt;/a&gt;&lt;p /&gt;  2. Check your &lt;tt&gt;plugin.xml&lt;/tt&gt; file, make sure it contains extension on &lt;tt&gt;org.eclipse.emf.ecore.generated_package&lt;/tt&gt; . Sample:&lt;p /&gt;  &lt;tt&gt;&amp;nbsp;&amp;nbsp; &amp;lt;extension point=&amp;quot;org.eclipse.emf.ecore.generated_package&amp;quot;&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;package&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; uri=&amp;quot;&lt;a href="http://www.bippo.co.id/shop/3.0/magentoconfig/1.0"&gt;http://www.bippo.co.id/shop/3.0/magentoconfig/1.0&lt;/a&gt;&amp;quot;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; class=&amp;quot;id.co.bippo.magento.config.MagentoConfigPackage&amp;quot;/&amp;gt;&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/extension&amp;gt;&lt;/tt&gt;&lt;p /&gt;  3. Check that you've (re-)generated your model classes. Open your &lt;tt&gt;.genmodel&lt;/tt&gt; and regenerate the Model.  &lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/3140968869349828376/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/how-to-solve-mwexpand-workflow.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/3140968869349828376?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/3140968869349828376?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/how-to-solve-mwexpand-workflow.html" title="How to Solve MWE/Xpand Workflow Problems/Errors" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DkcAR3s4fSp7ImA9Wx9RF00.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-2593179260710845476</id><published>2010-12-18T12:27:00.001-08:00</published><updated>2010-12-18T12:27:26.535-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-18T12:27:26.535-08:00</app:edited><title>Fixing Eclipse MWE Error: Workflow interrupted. Reason: Couldn't load resource under platform:/resource/*.xmi : org.eclipse.emf.ecore.xmi.PackageNotFoundException: Package with uri 'http://*' not found.</title><content type="html">&lt;div class='posterous_autopost'&gt;      If you ever tried to run an &lt;b&gt;&lt;a href="wiki.eclipse.org/Modeling_Workflow_Engine_(MWE)"&gt;Eclipse MWE&lt;/a&gt;&lt;/b&gt; &lt;b&gt;Workflow&lt;/b&gt;, most likely to do &lt;b&gt;M2T (Model-to-Text) transformation&lt;/b&gt; using &lt;a href="wiki.eclipse.org/Xpand"&gt;Xpand&lt;/a&gt; from an &lt;b&gt;EMF Ecore model&lt;/b&gt; to &lt;b&gt;text&lt;/b&gt; files, you'll surely encounter several errors at first (or later).&lt;p /&gt;  For my case, the error is as follows:&lt;p /&gt;  &lt;tt&gt;0&amp;nbsp;&amp;nbsp;&amp;nbsp; INFO&amp;nbsp; WorkflowRunner&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - --------------------------------------------------------------------------------------&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;7&amp;nbsp;&amp;nbsp;&amp;nbsp; INFO&amp;nbsp; WorkflowRunner&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - EMF Modeling Workflow Engine 1.0.0, Build v201008251122&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;7&amp;nbsp;&amp;nbsp;&amp;nbsp; INFO&amp;nbsp; WorkflowRunner&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - (c) 2005-2009 openarchitectureware.org and contributors&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;7&amp;nbsp;&amp;nbsp;&amp;nbsp; INFO&amp;nbsp; WorkflowRunner&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - --------------------------------------------------------------------------------------&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;8&amp;nbsp;&amp;nbsp;&amp;nbsp; INFO&amp;nbsp; WorkflowRunner&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - running workflow: /home/ceefour/project/Bippo/modeling_workspace/id.co.bippo.models/src/workflow/makegradle.mwe&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;8&amp;nbsp;&amp;nbsp;&amp;nbsp; INFO&amp;nbsp; WorkflowRunner&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - &lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;542&amp;nbsp; INFO&amp;nbsp; StandaloneSetup&amp;nbsp;&amp;nbsp;&amp;nbsp; - Registering platform uri '/home/ceefour/project/Bippo/modeling_workspace'&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;686&amp;nbsp; INFO&amp;nbsp; CompositeComponent - Reader: Loading model from platform:/resource/id.co.bippo.models/src/demo.bippo.co.id.xmi&lt;/tt&gt;&lt;br /&gt; &lt;tt&gt;780&amp;nbsp; ERROR WorkflowRunner&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; - Workflow interrupted. Reason: Couldn't load resource under platform:/resource/id.co.bippo.models/src/demo.bippo.co.id.xmi : org.eclipse.emf.ecore.xmi.PackageNotFoundException: Package with uri 'http://www.bippo.co.id/shop/3.0/magentoconfig/1.0' not found. (platform:/resource/id.co.bippo.models/src/demo.bippo.co.id.xmi, 2, 312)&lt;/tt&gt;&lt;p /&gt;  This seemed like the dreaded &lt;b&gt;platform:/resource URI&lt;/b&gt; common pitfall.&lt;p /&gt;  However, in my case the problem was inside the &lt;b&gt;.xmi model file&lt;/b&gt; itself :&lt;p /&gt;  &lt;tt&gt;xsi:schemaLocation=&amp;quot;&lt;a href="http://www.bippo.co.id/shop/3.0/magentoconfig/1.0"&gt;http://www.bippo.co.id/shop/3.0/magentoconfig/1.0&lt;/a&gt; &lt;/tt&gt;&lt;tt&gt;&lt;b&gt;../metamodel/magento-config.ecore&lt;/b&gt;&lt;/tt&gt;&lt;tt&gt;&amp;quot;&lt;/tt&gt;&lt;p /&gt;  I was moving the metamodel (Ecore model) to another folder/package, however the XMI file's &lt;tt&gt;schemaLocation&lt;/tt&gt; was hardcoded to a specific path.&lt;p /&gt;  Fix the schemaLocation, and it would work fine.  &lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/2593179260710845476/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/fixing-eclipse-mwe-error-workflow.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/2593179260710845476?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/2593179260710845476?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/fixing-eclipse-mwe-error-workflow.html" title="Fixing Eclipse MWE Error: Workflow interrupted. Reason: Couldn&amp;#39;t load resource under platform:/resource/*.xmi : org.eclipse.emf.ecore.xmi.PackageNotFoundException: Package with uri &amp;#39;http://*&amp;#39; not found." /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DU4GQHk_eyp7ImA9Wx9RFE8.&quot;"><id>tag:blogger.com,1999:blog-733023572967116656.post-1988491912969949253</id><published>2010-12-15T07:45:00.001-08:00</published><updated>2010-12-15T07:45:21.743-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-15T07:45:21.743-08:00</app:edited><title>Gradle Build Script (build.gradle) for Writing Gradle Plugins</title><content type="html">&lt;div class='posterous_autopost'&gt;      &lt;b&gt;&lt;a href="http://gradle.org"&gt;Gradle&lt;/a&gt;&lt;/b&gt; is a great build system written in &lt;a href="http://groovy.codehaus.org"&gt;Groovy programming language&lt;/a&gt; and that uses &lt;b&gt;build scripts&lt;/b&gt; written in Groovy as well.&lt;p /&gt;  There are several ways to write a &lt;a href="http://docs.codehaus.org/display/GRADLE/Plugins"&gt;Gradle plugin&lt;/a&gt; and the most extensible one (also the most complicated) is to build the plugin as a separate project.&lt;p /&gt;  I tried to find documentation on how to do this but I can only find actual guide for writing &amp;quot;embedded&amp;quot; Gradle plugins (the plugins are contained inside &lt;tt&gt;buildSrc&lt;/tt&gt; folder). But to move the plugin out of buildSrc folder and make it independent, you can use a &lt;tt&gt;build.gradle&lt;/tt&gt; build script file like this in your plugin:&lt;p /&gt;  &lt;p /&gt; &lt;tt&gt;apply {&lt;/tt&gt; &lt;tt&gt; plugin 'java'&lt;/tt&gt; &lt;tt&gt; plugin 'groovy'&lt;/tt&gt; &lt;tt&gt; plugin 'maven'&lt;/tt&gt; &lt;tt&gt; plugin 'eclipse'&lt;/tt&gt; &lt;tt&gt;}&lt;/tt&gt; &lt;tt&gt;group = 'gradle-plugin-javafx'&lt;/tt&gt; &lt;tt&gt;version = '0.2.0-SNAPSHOT'&lt;/tt&gt; &lt;tt&gt;dependencies {&lt;/tt&gt; &lt;tt&gt; compile gradleApi()&lt;/tt&gt; &lt;tt&gt; groovy localGroovy()&lt;/tt&gt; &lt;tt&gt;}&lt;/tt&gt;  &lt;br /&gt; Change group and version properties with your own.&lt;p /&gt;  Also, you can leave out applying the 'java', 'eclipse', and 'maven' plugins if you don't use them.&lt;p /&gt;  Source: &lt;a href="http://code.google.com/p/gradle-plugin-javafx/source/browse/build.gradle"&gt;http://code.google.com/p/gradle-plugin-javafx/source/browse/build.gradle&lt;/a&gt;  &lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://scala-enterprise.blogspot.com/feeds/1988491912969949253/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/gradle-build-script-buildgradle-for.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/1988491912969949253?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/733023572967116656/posts/default/1988491912969949253?v=2" /><link rel="alternate" type="text/html" href="http://scala-enterprise.blogspot.com/2010/12/gradle-build-script-buildgradle-for.html" title="Gradle Build Script (build.gradle) for Writing Gradle Plugins" /><author><name>Hendy Irawan</name><uri>http://www.blogger.com/profile/05192845149798446052</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_NtoTtHZadHE/SOPBu7htv5I/AAAAAAAAAAM/PuboJ3TrIBA/S220/hendy-sitting_square.jpg" /></author><thr:total>0</thr:total></entry></feed>
