<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" 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" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-19518284</atom:id><lastBuildDate>Fri, 20 Mar 2026 07:11:28 +0000</lastBuildDate><category>java</category><category>groovy</category><category>ast-transformation</category><category>dsl</category><category>ios</category><category>soa</category><category>web services</category><category>api</category><category>clojure</category><category>collections</category><category>docker</category><category>google-collection</category><category>groovy-1.7</category><category>jfreechart</category><category>jmx</category><category>swingbuilder</category><category>weblogic</category><category>activex</category><category>administration</category><category>aop</category><category>compojure</category><category>containerization</category><category>data-service</category><category>gae</category><category>gep3</category><category>grails</category><category>jaxb</category><category>kubernetes</category><category>leiningen</category><category>maven</category><category>middleware</category><category>mind-map</category><category>mule</category><category>oepe</category><category>osb</category><category>outlook</category><category>rss</category><category>scriptom</category><category>service bus</category><category>spring</category><category>spring-boot</category><title>Kartik Shah</title><description></description><link>http://blog.kartikshah.com/</link><managingEditor>noreply@blogger.com (Kartik Shah)</managingEditor><generator>Blogger</generator><openSearch:totalResults>35</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-2275812206351213216</guid><pubDate>Wed, 24 Aug 2016 02:19:00 +0000</pubDate><atom:updated>2016-08-23T22:04:16.826-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">containerization</category><category domain="http://www.blogger.com/atom/ns#">docker</category><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">kubernetes</category><title>Kubernetes Setup</title><description>&lt;p dir=&quot;ltr&quot;&gt;This post is a walkthrough for getting Kubernetes environment up and running. (Truly speaking, it is more of a self note to get Kubernetes environment running.) We will use Vagrant as Kubernetes provider to configure a Kubernetes cluster of VirtualBox VMs.&lt;/p&gt;&lt;p dir=&quot;ltr&quot;&gt;&lt;strong&gt;Prerequisities&lt;br&gt;&lt;/strong&gt;Get following componentes installed:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Kubernetes&lt;/li&gt;&lt;li&gt;Virtualbox&lt;/li&gt;&lt;li&gt;Vagrant&lt;/li&gt;&lt;li&gt;Docker&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Step 1: Configure and start Kubernetes&lt;/strong&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot;&gt;Note: One change I had to make with Kubernetes 1.3.3 running on Mac using Vagrant as Kubernetes provider is to instruct Vagrant to not create ssh keys. I modified the Vagrantfile in kubernetes install by adding &lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;code&gt;config.ssh.insert_key = false&lt;/code&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;To start a Kubernetes cluster &lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;export KUBERNETES_PROVIDER=vagrant 
export NUM_NODES=2 
cluster/kube-up.sh &lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;This will create three VirtualBox images namely master, node-1 and node-2. At the end of the process you will see messages on console like this. &lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;Kubernetes cluster is running.
The master is running at:
&amp;nbsp; https://10.245.1.2 
Administer and visualize its resources using Cockpit:
&amp;nbsp; https://10.245.1.2:9090 
For more information on Cockpit, visit http://cockpit-project.org 
The user name and password to use is located in /Users/kartik/.kube/config 

... calling validate-cluster 
Found 2 node(s).
NAME&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; STATUS&amp;nbsp; &amp;nbsp; AGE 
kubernetes-node-1&amp;nbsp; &amp;nbsp;Ready&amp;nbsp; &amp;nbsp; &amp;nbsp;4m 
kubernetes-node-2&amp;nbsp; &amp;nbsp;Ready&amp;nbsp; &amp;nbsp; &amp;nbsp;44s 
Validate output:
NAME&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;STATUS&amp;nbsp; &amp;nbsp; MESSAGE&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ERROR 
controller-manager&amp;nbsp; &amp;nbsp;Healthy&amp;nbsp; &amp;nbsp;ok &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;
scheduler&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Healthy&amp;nbsp; &amp;nbsp;ok &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;
etcd-0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Healthy&amp;nbsp; &amp;nbsp;{&quot;health&quot;: &quot;true&quot;} &amp;nbsp;&amp;nbsp;
etcd-1&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Healthy&amp;nbsp; &amp;nbsp;{&quot;health&quot;: &quot;true&quot;} &amp;nbsp;&amp;nbsp;
Cluster validation succeeded 
Done, listing cluster services:

Kubernetes master is running at https://10.245.1.2 
Heapster is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/heapster 
KubeDNS is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kube-dns 
kubernetes-dashboard is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard 
Grafana is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana 
InfluxDB is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb 

To further debug and diagnose cluster problems, use &#39;kubectl cluster-info dump&#39;.&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;&lt;strong&gt;Step 2: Run Docker image&lt;br&gt;&lt;/strong&gt;&lt;br&gt;Let’s start a simple Docker image. I will use the Spring Boot application Docker image that we create in the last blog entry - &lt;a href=&quot;http://blog.kartikshah.com/2016/07/setting-up-development-environment-with.html&quot; target=&quot;_blank&quot;&gt;Setting up development environment with Docker, Maven and IntelliJ&lt;/a&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot;&gt;To configure the authentication for Docker private repository&lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;code&gt;docker login [server]  &lt;/code&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;This will create credentials under your $HOME/.docker/config.json&lt;/p&gt;&lt;p dir=&quot;ltr&quot;&gt;To start docker image that is available locally on Docker&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;kubectl run options --image=kartikshah/options-analyzer --replicas=2 --port=8080 
deployment &quot;options&quot; created &lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;It will take a minute or so for the pods to get to Running status. If you catch them in act of starting up you will see ContrainerCreating Status.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;$ kubectl get pods 
NAME&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;READY&amp;nbsp; &amp;nbsp; &amp;nbsp;STATUS&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; RESTARTS&amp;nbsp; &amp;nbsp;AGE 
options-2554117421-5dwws&amp;nbsp; &amp;nbsp;0/1&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ContainerCreating&amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 11s 
options-2554117421-7ec17&amp;nbsp; &amp;nbsp;0/1&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ContainerCreating&amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 11s 

$ kubectl get pods 
NAME&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;READY&amp;nbsp; &amp;nbsp; &amp;nbsp;STATUS&amp;nbsp; &amp;nbsp; RESTARTS&amp;nbsp; &amp;nbsp;AGE 
options-2554117421-5dwws&amp;nbsp; &amp;nbsp;1/1&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Running&amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 4m 
options-2554117421-7ec17&amp;nbsp; &amp;nbsp;1/1&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Running&amp;nbsp; &amp;nbsp;0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 4m &lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;You can validate docker process is running by&lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;$ vagrant ssh node-1 -c &#39;sudo docker ps&#39;
CONTAINER ID&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; IMAGE&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; &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; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; COMMAND&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CREATED&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;STATUS&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PORTS&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;NAMES 
1b56f4a3222a&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; kartikshah/options-analyzer&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; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;java -Djava.security&quot;&amp;nbsp; &amp;nbsp;3 minutes ago&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Up 3 minutes&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; k8s_options.e44b7492_options-2554117421-5dwws_default_b7a648ff-5a58-11e6-9527-08002769954a_0da80b48 &lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;&lt;br&gt;&lt;strong&gt;Step 3: Find IP address of the node&lt;br&gt;&lt;/strong&gt;&lt;br&gt;Describe all to find the IP address of the node.&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;$ kube describe all&amp;nbsp;
…
Name:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; options-2554117421-7ec17 
Namespace:&amp;nbsp; &amp;nbsp; default 
Node:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; kubernetes-node-2/10.245.1.4 
Start Time:&amp;nbsp; &amp;nbsp; Thu, 04 Aug 2016 10:32:56 -0500 
Labels:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pod-template-hash=2554117421 
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; run=options 
Status:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Running 
IP:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 10.246.21.3 
…&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;The IP address listed agains “IP” is the IP address this node is known inside the cluster. You can run a simple curl command from inside the node&lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;$ vagrant ssh node-1 -c &#39;curl http://10.246.21.3:8080/&#39;
Hello Options Trader, how are you? Connection to 127.0.0.1 closed.&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br&gt;&lt;strong&gt;Step 4: Expose Service Loadbalancer&lt;/strong&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot;&gt;Now let’s expose the pods running on both nodes using a LoadBalancer. Kubernetes load balancer are deployed as Replication Controller (or newer Replication Set). There are three types of Load Balancer options: &lt;br&gt;1. ClusterIP - Exposes an IP only available from within Kubernetes Cluster&lt;br&gt;2. NodePort - Exposes special port on a special node IP, but load balances across nodes.&lt;br&gt;3. LoadBalancer - Only provided by cloud providers e.g. Google, AWS, OpenShift&lt;/p&gt;&lt;p dir=&quot;ltr&quot;&gt;There is active development going on providing the LoadBalancer option on bare metal Kubernetes deployment. You can read more about it here at &lt;a href=&quot;https://github.com/kubernetes/contrib/blob/master/service-loadbalancer/README.md&quot; target=&quot;_blank&quot; title=&quot;service-loadbalancer&quot;&gt;service-loadbalancer&lt;/a&gt;&lt;/p&gt;&lt;p dir=&quot;ltr&quot;&gt;We will use NodePort type of replication set to expose as service to outside world. &lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;$ kubectl expose rs options-2554117421 --port=8080 --target-port=8080 --name=option-service --type=NodePort 
service &quot;option-service&quot; exposed &lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;Describe the service to get node ip and port that is exposed to host machine. &lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;$ kubectl describe service
… 
Name:            option-service 
Namespace:        default 
Labels:            pod-template-hash=2554117421 
            run=options 
Selector:        pod-template-hash=2554117421,run=options 
Type:            NodePort 
IP:            10.247.237.53 
Port:                8080/TCP 
NodePort:            30728/TCP 
Endpoints:        10.246.21.3:8080,10.246.33.5:8080 
Session Affinity:    None 
...
&lt;/code&gt;&lt;/pre&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;Now you can access the service from you host machine. In my case from the Mac which is running the VirtualBox VMs. &lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;$ curl http://10.245.1.4:30728/
Hello Options Trader, how are you?&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;There you have it - a Kubernetes cluster running a Docker image across multiple VMs (nodes) with NodePort loadbalancing.&lt;/p&gt;&lt;p dir=&quot;ltr&quot;&gt;&lt;strong&gt;Step 5: Console &lt;br&gt;&lt;/strong&gt;This step is optional. If you want to explore the Kubernetes dashboard UI, you have to setup a private certificate. One of the ways Kubernetes dashboard UI authenticates is via identity cert. You can create this identity cert as follows: &lt;br&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;#Copy the certs from master node
vagrant ssh master-c &#39;sudo cp /srv/kubernetes/kubecfg.* /vagrant/ &amp;amp;&amp;amp; sudo cp /srv/kubernetes/ca.crt /vagrant/&#39;
#Move them to separate folder
mv kubecfg.* ../certs/ &amp;amp;&amp;amp; mv ca.crt ../certs/
#Create private cert using open ssl
openssl pkcs12 -export -clcerts -inkey ../certs/kubecfg.key -in ../certs/kubecfg.crt -out kubecfg.p12 -name &quot;ks-kubecfg”
#For Mac only; open the private cert to install it in Keychain Access
open kubecfg.12&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p dir=&quot;ltr&quot;&gt;Now you can visit the dashboard by visiting the URL provided at the startup message. &lt;br&gt;&lt;a href=&quot;http://https//10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard&quot; target=&quot;_blank&quot;&gt;https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.kartikshah.com/2016/08/kubernetes-setup.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-8205260591791595488</guid><pubDate>Fri, 22 Jul 2016 22:40:00 +0000</pubDate><atom:updated>2016-07-22T17:41:35.366-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">docker</category><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">maven</category><category domain="http://www.blogger.com/atom/ns#">spring</category><category domain="http://www.blogger.com/atom/ns#">spring-boot</category><title>Setting up development environment with Docker, Maven and IntelliJ</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;background-color: white; font-family: &amp;quot;verdana&amp;quot; , sans-serif; font-size: 14px; text-indent: 18px;&quot;&gt;This post walks through the setup of development environment for Docker with IntelliJ using Maven. We will use a Spring boot application and configure IntelliJ for iterative development.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: &amp;quot;verdana&amp;quot; , sans-serif; font-size: 14px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;strong style=&quot;color: #0b5394; font-size: 16px; text-indent: 18px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;Spring Boot Application&lt;/span&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;The demo application is a simple one page app which displays a chart of VIX index. We will wire &lt;a href=&quot;https://www.quandl.com/&quot;&gt;Quandl’s&lt;/a&gt; web service to fetch the historical data about VIX index and use &lt;a href=&quot;http://canvasjs.com/&quot;&gt;CanvasJS&lt;/a&gt; charting library to display the chart. You can learn more about Spring Boot application with this&lt;/span&gt;&lt;span style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://spring.io/guides/gs/spring-boot/&quot; style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;Spring Guide&lt;/a&gt;&lt;span style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;Here are some highlights:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;strong style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/strong&gt;
&lt;strong style=&quot;color: #b45f06; font-size: 14px; text-indent: 18px;&quot;&gt;Application.java&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif; font-size: 14px; text-indent: 18px;&quot;&gt;@SpringBootApplication is the convenience annotation that marks the class as an entry point.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/kartikshah/37e0c37954ee69dd8a990a72c8f3ac52.js&quot;&gt;&lt;/script&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;strong style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/strong&gt;
&lt;strong style=&quot;color: #b45f06; font-size: 14px; text-indent: 18px;&quot;&gt;AppConfig.java&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;Setup Spring wiring using java in this class. It is any class that is marked with @Configuration annotation.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/kartikshah/7261a89bd42e5d839afda6329e1b6d1a.js&quot;&gt;&lt;/script&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;strong style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/strong&gt;
&lt;strong style=&quot;color: #b45f06; font-size: 14px; text-indent: 18px;&quot;&gt;View - JSPs&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif; font-size: 14px; text-indent: 18px;&quot;&gt;Application’s view pages are under /webapp/WEB-INF/jsp.&amp;nbsp; application.properties file provided configuration to wire Spring’s view resolver.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;strong style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/strong&gt;
&lt;strong style=&quot;color: #b45f06; font-size: 14px; text-indent: 18px;&quot;&gt;Static Content&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif; font-size: 14px; text-indent: 18px;&quot;&gt;Application’s static content under src/main/resources/static as below.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif; font-size: 14px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://kartikshah.com/blog/spring-boot-resources.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://kartikshah.com/blog/spring-boot-resources.png&quot; height=&quot;181&quot; width=&quot;320&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;You can find entire source code &lt;a href=&quot;https://github.com/kartikshah/options-analyzer&quot;&gt;here on github&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;strong style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/strong&gt;
&lt;strong style=&quot;color: #b45f06; font-size: 14px; text-indent: 18px;&quot;&gt;pom.xml&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif; font-size: 14px; text-indent: 18px;&quot;&gt;spring-boot-maven-plugin make executing lifecycle events easier. If you open IntelliJ’s Maven window, you will see all spring-boot-run, which will allow you to run the project. You can also create run configuration for easy access.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif; font-size: 14px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://kartikshah.com/blog/spring-boot-pom-intellij.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://kartikshah.com/blog/spring-boot-pom-intellij.png&quot; height=&quot;320&quot; width=&quot;199&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;strong style=&quot;background-color: white; font-size: 16px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/strong&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;strong style=&quot;color: #0b5394; font-size: 16px; text-indent: 18px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;strong style=&quot;color: #0b5394; font-size: 16px; text-indent: 18px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;Setting up Docker&lt;/span&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;span style=&quot;background-color: white; font-size: 14px; text-indent: 18px;&quot;&gt;You can setup Docker environment by following instructions from&lt;/span&gt;&lt;span style=&quot;background-color: white; font-size: 14px; text-indent: 18px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;a data-mce-href=&quot;http://https://docs.docker.com/docker-for-mac/&quot; href=&quot;http://https//docs.docker.com/docker-for-mac/&quot; style=&quot;background-color: white; font-size: 14px; text-indent: 18px;&quot;&gt;docker for mac documentation&lt;/a&gt;&lt;span style=&quot;background-color: white; font-size: 14px; text-indent: 18px;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;strong style=&quot;color: #0b5394; font-size: 16px; text-indent: 18px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;strong style=&quot;color: #0b5394; font-size: 16px; text-indent: 18px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;Docker, Maven and IntelliJ&lt;/span&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif; text-indent: 18px;&quot;&gt;We will use docker-maven-plugin from com.spotify&lt;/span&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;b style=&quot;text-indent: 18px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;b style=&quot;color: #b45f06; text-indent: 18px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;Docker file&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif; text-indent: 18px;&quot;&gt;Create src/main/docker/Dockerfile.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;script src=&quot;https://gist.github.com/kartikshah/c88b039a7cbc3085897df598ec3e27b0.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;strong style=&quot;color: #b45f06; text-indent: 18px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;pom.xml&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;Configuration for docker plugin&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;script src=&quot;https://gist.github.com/kartikshah/45aebab8bec4178142e6db692a1c56d1.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;span style=&quot;text-indent: 18px;&quot;&gt;ServerId tag specifies the docker repository you want to push to. The credentials to the serverId needs to be provided in your maven settings.xml. You have option of mvn encrypting the password. Follow instructions&amp;nbsp;&lt;/span&gt;&lt;a data-mce-href=&quot;https://maven.apache.org/guides/mini/guide-encryption.html#How_to_encrypt_server_passwords&quot; href=&quot;https://maven.apache.org/guides/mini/guide-encryption.html#How_to_encrypt_server_passwords&quot; style=&quot;text-indent: 18px;&quot;&gt;here&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;script src=&quot;https://gist.github.com/kartikshah/9a450643f3aa3066204a65a2be763dfb.js&quot;&gt;&lt;/script&gt;

&lt;br /&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;strong style=&quot;text-indent: 18px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;strong style=&quot;color: #b45f06; text-indent: 18px;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;Run Configuration&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif; text-indent: 18px;&quot;&gt;To get it running in IntelliJ, you can setup Run Configuration as follows:&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; text-indent: 18px; font-size: 14px; line-height: normal; font-family: Cochin;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; text-indent: 18px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;1. Open Run -&amp;gt; Edit Configuration&lt;/span&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; text-indent: 18px; font-size: 14px; line-height: normal; font-family: Cochin;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; text-indent: 18px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;2. Add Maven Configuration&lt;/span&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; text-indent: 18px; font-size: 14px; line-height: normal; font-family: Cochin;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; text-indent: 18px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;3. Provide maven command line as clean package docker:build&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://kartikshah.com/blog/docker-intellij-run-config-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://kartikshah.com/blog/docker-intellij-run-config-1.png&quot; height=&quot;111&quot; width=&quot;320&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; text-indent: 18px; font-size: 12px; line-height: normal; font-family: Helvetica;&quot; style=&quot;background-color: white; font-size: 12px; line-height: normal; text-indent: 18px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; text-indent: 18px; font-size: 14px; line-height: normal; font-family: Cochin;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; text-indent: 18px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;4. Go to the Runner tab and provide environment variables&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://kartikshah.com/blog/docker-intellij-run-config-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://kartikshah.com/blog/docker-intellij-run-config-2.png&quot; height=&quot;66&quot; width=&quot;320&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;http://kartikshah.com/blog/docker-intellij-run-config-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://kartikshah.com/blog/docker-intellij-run-config-3.png&quot; height=&quot;101&quot; width=&quot;320&quot; /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; font-size: 12px; line-height: normal; font-family: Helvetica;&quot; style=&quot;background-color: white; font-size: 12px; line-height: normal;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;\22 verdana\22 &amp;quot; , sans-serif; font-size: 14px; text-indent: 18px;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;5. Similarly, you can also create docker:push run configuration, if you want to push docker image to docker registry.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;\22 verdana\22 &amp;quot; , sans-serif; font-size: 14px; text-indent: 18px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div data-mce-style=&quot;margin: 0px; text-indent: 18px; font-size: 14px; line-height: normal; font-family: Cochin; min-height: 17px;&quot; style=&quot;background-color: white; font-size: 14px; line-height: normal; min-height: 17px; text-indent: 18px;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</description><link>http://blog.kartikshah.com/2016/07/setting-up-development-environment-with.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-6597217547523897487</guid><pubDate>Tue, 14 Oct 2014 04:33:00 +0000</pubDate><atom:updated>2014-10-13T23:33:48.001-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">soa</category><category domain="http://www.blogger.com/atom/ns#">web services</category><title>Web Service implemented as JAX-WS and JAX-RS</title><description>&lt;p&gt;
&lt;span style=&quot;color: #222222; font-size: 14px; font-family: Verdana;&quot;&gt;This post walks you through exposing a java web service implementation as both SOAP and REST service. This project uses Apache CXF as a framework to implement JAX-WS and JAX-RS based service on same implementation class.&lt;/span&gt;
&lt;/p&gt;
&lt;span style=&quot;font-size: 14px; font-family: Verdana;&quot;&gt;
&lt;a style=&quot;color: #1155cc; font-family: Verdana; font-size: 14px;&quot; href=&quot;https://github.com/kartikshah/sample-soap-rest&quot; target=&quot;_blank&quot;&gt;https://github.com/kartikshah/sample-soap-rest&lt;/a&gt;&lt;/span&gt;&lt;br style=&quot;color: #222222; font-family: Verdana; font-size: 14px;&quot; /&gt;

&lt;p&gt;&lt;strong style=&quot;font-family: Verdana; font-size: 14px; color: #0a5394;&quot;&gt;Web Service Interface&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #222222; font-family: Verdana; font-size: large;&quot;&gt;Here is the simple web service interface that has the annotations to expose it as both JAX-WS and JAX-RS endpoint.&lt;/span&gt;&lt;/p&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://gist.github.com/kartikshah/3160df2d0ff06d21eba5.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 14px; font-family: Verdana;&quot;&gt;&lt;strong&gt;&lt;span style=&quot;color: #0a5394;&quot;&gt;Contract - WSDL and WADL&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #222222; font-size: 14px; font-family: Verdana;&quot;&gt;One of the crucial benefit of web service is that contract is either written or generated which serves as integration document. For that purpose, in my opinion, it is essential that either a WSDL or WADL is generated for methods exposed as web service. This applies specifically when using implementation first approach. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #222222; font-family: Verdana; font-size: 14px;&quot;&gt;&lt;em&gt;WADL&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #222222; font-family: Verdana; font-size: 14px;&quot;&gt;&lt;script src=&quot;https://gist.github.com/kartikshah/3acab4584eb3728d6fa0.js&quot;&gt;&lt;/script&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #222222; font-family: Verdana; font-size: 14px;&quot;&gt;You can also generate WADL in JSON form by appending&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style=&quot;color: #222222; font-family: Verdana; font-size: 14px;&quot;&gt;?_wadl&amp;amp;_type=json&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span style=&quot;color: #222222; font-family: Verdana; font-size: 14px;&quot;&gt;&lt;span style=&quot;color: #222222; font-family: Verdana; font-size: 14px;&quot;&gt;&lt;script src=&quot;https://gist.github.com/kartikshah/df5b5281ed023df8398e.js&quot;&gt;&lt;/script&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong style=&quot;color: #0a5394; font-family: Verdana; font-size: 14px;&quot;&gt;WADL generation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #222222; font-size: 14px; font-family: Verdana;&quot;&gt;WadlGenerator configuration in spring application context is key to generating correctly linked representation.&lt;/span&gt;&lt;br style=&quot;color: #222222; font-family: arial, sans-serif; font-size: 13px;&quot; /&gt;&lt;br style=&quot;color: #222222; font-family: arial, sans-serif; font-size: 13px;&quot; /&gt;&lt;span style=&quot;color: #222222; font-size: 14px; font-family: Verdana;&quot;&gt;&lt;script src=&quot;https://gist.github.com/kartikshah/e0386511b0a0a3e9a862.js&quot;&gt;&lt;/script&gt;&lt;/span&gt;&lt;br style=&quot;color: #222222; font-family: arial, sans-serif; font-size: 13px;&quot; /&gt;&lt;br style=&quot;color: #222222; font-family: arial, sans-serif; font-size: 13px;&quot; /&gt;&lt;br /&gt;&lt;/p&gt;</description><link>http://blog.kartikshah.com/2014/10/web-service-implemented-as-jax-ws-and.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-7946927139323320146</guid><pubDate>Sat, 11 Jan 2014 21:41:00 +0000</pubDate><atom:updated>2014-08-09T16:37:30.960-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ios</category><title>Autolayout and Orientation</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;This is a sample project which demonstrates following:&lt;/span&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;Use of Autolayout to setup proportional views&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;Use of Autolayout programmatically to move subviews to support different orientation&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;Consider following contrieved example where we have different layout for landscape and portrait for set of controls.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;br /&gt;&lt;/span&gt;


&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;img alt=&quot;Landscape&quot; src=&quot;http://kartikshah.com/blog/blog-autolayout-landscape.png&quot; height=&quot;437&quot; width=&quot;559&quot; /&gt;&lt;/span&gt;

&lt;br /&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;img alt=&quot;&quot; src=&quot;http://kartikshah.com/blog/blog-autolayout-portrait.png&quot; height=&quot;575&quot; width=&quot;420&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;strong&gt;Steps and Explanation&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;em&gt;Divide sections of the screen into subview&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt; Group the controls into some sort of organization based on relationship among them. Use subviews to arrange them as in sample above. The subviews does not need to have visual characteristics as background color or borders. The colors used above is just for easier visualization.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;em&gt;Define the horizontal and vertical constraints using visual programming language&lt;/em&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt; To make the task of defining constraints easier inspect the expected result for both orientation. Come up constraints for the leftView and rightView in relation with containerView.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;For Landscape,&lt;/span&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;Horizontal Constraints: [superView]-[leftView]-[rightView]-[superView] ==&amp;gt; H:|-[leftView]-[rightView]-|&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;Vertical Constraints: [superView]-[leftView]-[superView] &amp;nbsp;==&amp;gt; V:|-[leftView]-| and&amp;nbsp;[superView]-[rightView]-[superView]V:|-[rightView]-|&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;leftView.width = factor x rightView.width (Factor for same width = 1.0)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;leftView.height = rightView.height (Factor for same height = 1.0)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;For Portrait,&lt;/span&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;Horizontal constraint: [superView]-[leftView]-[superView] ==&amp;gt; H:|-[LeftView]-| and [superView]-[rightView]-[superView] ==&amp;gt; H:|-[rightView]-|&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;Vertical constraint: [superView]-[leftView]-[rightView]-[superView] ==&amp;gt; V:|-[leftView]-[rightView]-|&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;leftView.height = factor x rightView.height (Factor for same height = 1.0)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;leftView.width = rightView.width (Factor for same width = 1.0)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;em&gt;Code updateViewConstraints method&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt; For Landscape:&lt;/span&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/kartikshah/8278826.js&quot;&gt;&lt;/script&gt;
&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt; For Portrait: &lt;/span&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/kartikshah/8278826.js&quot;&gt;&lt;/script&gt;

&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;Complete source code at:&amp;nbsp;&lt;a href=&quot;https://github.com/kartikshah/AutoLayoutTemplate&quot;&gt;https://github.com/kartikshah/AutoLayoutTemplate&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
</description><link>http://blog.kartikshah.com/2014/01/autolayout-and-orientation_11.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-6829529729211715540</guid><pubDate>Sun, 30 Jun 2013 18:46:00 +0000</pubDate><atom:updated>2014-08-09T16:37:30.955-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ios</category><title>Hidden Design Elements</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;font-size: 14px; text-indent: 18px;&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;font-size: 18px; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif; font-size: 14px;&quot;&gt;There are many design elements to consider while creating iOS apps. Some of these elements your users can notice visually. And some of these elements are hidden which users will notice while experiencing the app.&lt;/span&gt;&lt;span style=&quot;font-family: Verdana, sans-serif; font-size: 14px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;font-size: 18px; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif; font-size: 14px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;color: #0b5394; font-family: Verdana, sans-serif;&quot;&gt;Elements that users see&lt;/span&gt;&lt;/h3&gt;
&lt;div style=&quot;min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;There are aspects of design that your users can see. They exists on the screen. They can see them and they can interact with some of them. These aspects differ for different types of app.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;min-height: 15px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;i&gt;&lt;/i&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Users will look at how components are laid out on the screen. They will notice the choice of UI component. Text on the app conveys information. Users will notice its readability. It needs to be easy to read for your demographics. Graphics styles your app. Creative assets needs to align with the purpose of the app. Most essentially it needs to connect with your user. Users will notice if it doesn’t.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;

&lt;br /&gt;
&lt;h3 style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;color: #0b5394; font-family: Verdana, sans-serif;&quot;&gt;Elements that users notice&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;There are aspects of design that user won’t see. But they will notice their absence. Here are some of these hidden design elements. (This is by no means an exhaustive list)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;

&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;&lt;span style=&quot;color: #b45f06; font-family: Verdana, sans-serif;&quot;&gt;Consistency&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Consistency reinforces designs’ purpose. It reinforces behavior. It makes it easy for the user to remember actions they want to perform. It makes interaction obvious. &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;i&gt;Consistent use of UI component.&lt;/i&gt; Decide which UI components best serve the purpose for a specific action in UI. Stick with same component throughout the app for similar usage pattern. For example, if app displays user agreements, privacy policy in which user has to agree, use similar controls for accept/decline, use similar controls to display agreement text.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;i&gt;Consistent use of navigational flow.&lt;/i&gt; It is essential to determine patterns for navigational flow. Define navigational pattern used for sub flows within apps and stick to it consistently. If it is drill down navigation, provide consistent controls to go further or go back. Reinforce next/back actions by providing them in specific place on the screen. If popover window slides up, make sure similar transition is applied to screens following same action.&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;There could be exceptions to consistency. Define why exception is required and use it sparingly and judiciously.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;

&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;&lt;span style=&quot;color: #b45f06; font-family: Verdana, sans-serif;&quot;&gt;Simplicity&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Complexity within the app points to job half done. Take time to simplify.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;i&gt;Simplify complex UI&lt;/i&gt;. If a single screen is doing more than one primary function, simplify the screen. Limit the number of popovers from single screen. Avoid gestures that are not optimum for certain screen sizes. For example, three/four finger gestures aren’t well suited for smaller screen. Screen has a functional need to display too much data, find a way to display information in simple manner.&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;i&gt;Simplify any complex navigation flows&lt;/i&gt;. Find simpler organization for screens where wizards have too many steps. Avoid deep drill downs where users can’t track their way backwards. Keep navigational flow linear, don’t branch and re-branch off into sub flows. If that is functional need abstract that complexity out from user. &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;i&gt;Simplify configuration options.&lt;/i&gt; Provide a quick way to start using the app. Users rely on app designer to prepare the optimum default configuration for the app. If app requires too many steps to start using the app, users will balk in the setup process.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;&lt;span style=&quot;color: #b45f06; font-family: Verdana, sans-serif;&quot;&gt;Responsiveness&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;i&gt;Responsiveness of UI&lt;/i&gt; is of utmost importance. Make sure that UI actions are not starving for resources against other time consuming operations. Move those non-UI time consuming operations to background queues. Transitions are required to be smooth. Slides and swooshes of UI elements provides context to subconscious mind. If they get slow or waiting to load data, its effectiveness is reduced and purpose unachieved.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;

&lt;br /&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;&lt;span style=&quot;color: #b45f06; font-family: Verdana, sans-serif;&quot;&gt;Visual Cues&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;i&gt;Use visual cues effectively.&lt;/i&gt; Effective use visual cues to make user aware of hidden gestures. Gestures like swipe for split views and page controls are not easily obvious to certain users. Use visual cues like bounce to make user aware of such available interactions.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;i&gt;Use Transitions appropriately.&lt;/i&gt; Use transitions correctly to display additional screens. If popovers or modal windows are sliding up it makes sense if they slide down when dismissed. Avoid transitions from all edges the screen.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h4 style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;&lt;span style=&quot;color: #b45f06; font-family: Verdana, sans-serif;&quot;&gt;Information Presentation&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Present information user wants to know at correct level. Present it at level which is most logical. Present it at too high level and user will have to navigate deeper to get the information they need. Present it too detail and users will get overwhelmed by information.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;min-height: 17px;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Finally remember this. &lt;b&gt;Users will notice when hidden design elements are missing.&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
</description><link>http://blog.kartikshah.com/2013/06/hidden-design-elements.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-873673106162990567</guid><pubDate>Fri, 10 May 2013 03:18:00 +0000</pubDate><atom:updated>2014-08-09T16:37:30.964-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ios</category><title>How to make Xcode use latest SVN Client</title><description>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Recently working on an iOS project faced an issue importing project to subversion. All svn commands worked fine from command line, but would not work from &lt;i&gt;Organizer.&amp;nbsp;&lt;/i&gt;&lt;span style=&quot;-webkit-composition-fill-color: rgba(175, 192, 227, 0.230469); -webkit-composition-frame-color: rgba(77, 128, 180, 0.230469); -webkit-tap-highlight-color: rgba(26, 26, 26, 0.296875);&quot;&gt;The issue turned out to be incompatibility between svn client version to the version on subversion server. Xcode was using svn client bundled within Xcode app, while I had later version of the client installed elsewhere available on path.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;-webkit-composition-fill-color: rgba(175, 192, 227, 0.230469); -webkit-composition-frame-color: rgba(77, 128, 180, 0.230469); -webkit-tap-highlight-color: rgba(26, 26, 26, 0.296875);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;-webkit-composition-fill-color: rgba(175, 192, 227, 0.230469); -webkit-composition-frame-color: rgba(77, 128, 180, 0.230469); -webkit-tap-highlight-color: rgba(26, 26, 26, 0.296875);&quot;&gt;Here is how you can point Xcode to use latest version of svn.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;-webkit-composition-fill-color: rgba(175, 192, 227, 0.230469); -webkit-composition-frame-color: rgba(77, 128, 180, 0.230469); -webkit-tap-highlight-color: rgba(26, 26, 26, 0.296875);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;script src=&quot;https://gist.github.com/kartikshah/5552075.js&quot;&gt;&lt;/script&gt;&lt;/div&gt;
</description><link>http://blog.kartikshah.com/2013/05/how-to-make-xcode-use-latest-svn-client.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-1173168734314185999</guid><pubDate>Wed, 01 Feb 2012 21:02:00 +0000</pubDate><atom:updated>2012-02-01T15:14:29.532-06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">jaxb</category><category domain="http://www.blogger.com/atom/ns#">web services</category><title>JAXB - Unmarshal non root element</title><description>&lt;div&gt;&lt;div&gt;&lt;p&gt;While generating JAX-WS web service client code using wsimport, it generates Object factory top level method input and output type. This restricts the use to marshal and unmarshal classes which are contained within the top level objects.&lt;/p&gt;&lt;div&gt;More often than not, top level Schema objects are non-domain specific objects like MethodInput/MethodOutput. You can unmarshal them using ObjectFactory&lt;/div&gt;&lt;p&gt;&lt;strong&gt;ObjectFactory.java&lt;/strong&gt;&lt;br /&gt;&lt;script src=&quot;https://gist.github.com/1719247.js&quot;&gt; &lt;/script&gt;&lt;br /&gt; &lt;strong&gt;query.xml&lt;/strong&gt;&lt;br /&gt;&lt;script src=&quot;https://gist.github.com/1719283.js&quot;&gt; &lt;/script&gt;&lt;br /&gt; &lt;strong&gt;MethodInput.java&lt;/strong&gt;&lt;br /&gt;&lt;script src=&quot;https://gist.github.com/1719278.js&quot;&gt; &lt;/script&gt;&lt;br /&gt; &lt;strong&gt;JaxbUnmarshallerMethodInput.java&lt;/strong&gt;&lt;br /&gt;&lt;script src=&quot;https://gist.github.com/1719145.js&quot;&gt; &lt;/script&gt;&lt;/p&gt;&lt;div&gt;But if you want to unmarshal XML chunks of objects contained within those top level object, the same approach does not work, if those generated classes are not included as part of ObjectFactory or they do not have annotation @XmlRootElement on top of that.&lt;/div&gt;&lt;p&gt;&lt;strong&gt;account.xml&lt;/strong&gt;&lt;br /&gt;&lt;script src=&quot;https://gist.github.com/1719498.js&quot;&gt; &lt;/script&gt;&lt;/p&gt;&lt;div&gt;&lt;strong&gt;Option 1&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;So the obvious option is to add @XmlRootElement to any generated classes that you want to unmarshal directly, but when you are using wsdls are from an external source, idea of updating generated classes breaks the process.&amp;nbsp;&lt;/div&gt;&lt;p&gt;&lt;script src=&quot;https://gist.github.com/1719264.js&quot;&gt; &lt;/script&gt;&lt;/p&gt;&lt;div&gt;&lt;strong&gt;Option 2&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;Another option is to pass the child element&#39;s Node object to unmarshal&amp;nbsp;&lt;/div&gt;&lt;p&gt;&lt;script src=&quot;https://gist.github.com/1719270.js&quot;&gt; &lt;/script&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2012/02/jaxb-unmarshal-non-root-element.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-3398658744809993126</guid><pubDate>Sat, 09 Jul 2011 18:15:00 +0000</pubDate><atom:updated>2014-08-09T16:46:44.677-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">soa</category><category domain="http://www.blogger.com/atom/ns#">weblogic</category><title>SOA Composite deployment - Oracle SOA Suite</title><description>&lt;div&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;font-family: Menlo; font-size: medium;&quot;&gt;&lt;span style=&quot;font-family: Menlo;&quot;&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;&lt;strong&gt;&lt;span style=&quot;border-collapse: separate; color: #000000; font-family: Times; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;&quot;&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;This post is going to be about very specific subject - SOA Composite deployment on Oracle SOA Suite. I am going to capture few issues faced while deploying SOA composite.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt; &lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; min-height: 15px; margin: 0px;&quot;&gt;&lt;span style=&quot;border-collapse: separate; color: #000000; font-family: Menlo; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: small;&quot;&gt;&lt;span style=&quot;font-family: Menlo;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;br /&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;border-collapse: separate; color: #000000; font-family: Menlo; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: small;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;strong&gt;Sample Composite&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;For purpose of this blog, consider a simple SOA composite that does the following:&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Read entries from a database&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Create XML from the entries&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Store XML entries to another database&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Read XML entries&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Post each XML entry to a web service&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; min-height: 15px; margin: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;There is good amount of workflow and business logic that makes it a perfect use case for doing it with BPEL, but that is beyond the purpose of this entry.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; min-height: 15px; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;br /&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;strong&gt;Composite Dependencies&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Sample SOA composite had following dependencies:&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Couple of Datasource (one to read source data and other to store XML Entries)&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;JMS Queue (Weblogic&amp;rsquo;s Uniform Distributed Queues)&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;strong&gt;Deployment Process&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;em&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;1. Datasources&lt;/span&gt;&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;em&gt;Create Generic Datasources&lt;/em&gt;&amp;nbsp;pointing to individual Oracle RAC node and a&amp;nbsp;&lt;em&gt;Multi Datasource&lt;/em&gt;&amp;nbsp;using WLST scripts. (Most of the scripts are written for Weblogic 10.3.3, so haven&amp;rsquo;t explored newly introduced GridLinked Datasource in Weblogic 10.3.4.)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; min-height: 15px; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;br /&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;em&gt;2. JMS Resources&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Create JMS Server, JMS Module, Sub deployment, Connection Factory and JMS Queues using WLST scripts.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; min-height: 15px; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;br /&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;em&gt;3. DBAdapter.rar&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;The composite uses DBAdapter connector to interact with databases, so add outbound connection pools the DBAdapter.rar pointing to actual Weblogic Datasources and redeploy application&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; min-height: 15px; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;br /&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;4. Deploy Composite&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Finally, deploy the composite using Enterprise Manager Console.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; min-height: 15px; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;br /&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;strong&gt;Lessons Learned&amp;nbsp;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;strong&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;&lt;br /&gt; &lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;strong&gt;1. Server Start parameters&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Using Enterprise Manager to deploy, the deployment window got stuck and never returned back. The issue, it turns out, is that the deployment was not able to communicate among instance servers. If SOA cluster is using multicast to communicate across weblogic instances, you will required following parameters on each server instance. The parameter adds well known address&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-family: &#39;Andale Mono&#39;;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;-Dtangosol.coherence.wka1=soa01.mycompany.com&amp;nbsp;-Dtangosol.coherence.wka2=soa02.&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;http://suddenlink.cequel3.com/&quot;&gt;&lt;span style=&quot;font-family: &#39;Andale Mono&#39;;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;m&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: &#39;Andale Mono&#39;;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;ycompany.com&amp;nbsp;-Dtangosol.coherence.localhost=soa01.mycompany.com&amp;nbsp;-Xmx2048m&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;strong&gt;2. Failure updating DBAdapter.rar connector application&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;On attempt to create outbound connection pool pointing to weblogic datasource, activation fails complaining FileNotFoundException: Plan.xml. The file is present on the primary server instance, but it isn&#39;t replicated on other nodes. I am not sure why but for some reason the Plan.xml was required to present on all the nodes, even if deployment is being done from machine with AdminServer.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; min-height: 15px; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;br /&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;strong&gt;3. Failure on interaction with DB on some instances.&amp;nbsp;&amp;nbsp;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;Even after the deployment was successful, any DB activities from nodes other than primary node failed giving following error:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style=&quot;font-family: &#39;Andale Mono&#39;;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;BINDING.JCA-12511&lt;br /&gt; JCA Binding Component connection issue.&lt;br /&gt; JCA Binding Component is unable to create an outbound JCA (CCI) connection.&lt;br /&gt; apptools:InsertLogDB [ InsertLogDB_ptt::insert(TestLogCollection,TestLogCollection) ] : The JCA Binding Component was unable to establish an outbound JCA CCI connection due to the following issue: BINDING.JCA-12510&amp;nbsp;JCA Resource Adapter location error.&lt;br /&gt; Unable to locate the JCA Resource Adapter via .jca binding file element &amp;lt;connection-factory/&amp;gt;&amp;nbsp;The JCA Binding Component is unable to startup the Resource Adapter specified in the &amp;lt;connection-factory/&amp;gt; element:&amp;nbsp; location=&#39;eis/DB/application-ds&#39;.&amp;nbsp;The reason for this is most likely that either&amp;nbsp;1) the Resource Adapters RAR file has not been deployed successfully to the WebLogic Application server or&amp;nbsp;2) the &#39;&amp;lt;jndi-name&amp;gt;&#39; element in weblogic-ra.xml has not been set to eis/DB/application-ds. In the last case you will have to add a new WebLogic JCA connection factory (deploy a RAR).&amp;nbsp;Please correct this and then restart the Application Server&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Please make sure that the JCA connection factory and any dependent connection factories have been configured with a sufficient limit for max connections. Please also make sure that the physical connection to the backend EIS is available and the backend itself is accepting connections.&lt;/p&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;One noticeable thing on weblogic console was that under testing tab of DBAdapter.rar all outbound connection pools were not visible. The issue is that updated Plan.xml is not replicated to all other nodes. You have to manually copy the Plan.xml containing all outbound connection pool to all server instance nodes.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;Here is what you need to do:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;ul&gt;&lt;li style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Copy the Plan.xml containing all outbound connection pool to all nodes&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Update the connector application DBAdapter.rar&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;Restart DBAdapter.rar and Application server instance&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; min-height: 15px; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;br /&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;&lt;strong&gt;4. BAM Cluster Multicast misconfiguration&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; font-family: verdana, geneva;&quot;&gt;A misconfiguration on the Multicast address of BAM cluster resulted in Access Forbidden 403. The issue was that BAM server was trying to communicate with another environment cluster. (i.e. prod bam cluster trying to communicate with test bam cluster).&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;Here is the error:&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span style=&quot;font-family: &#39;Andale Mono&#39;;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;&amp;lt;BEA-000141&amp;gt; &amp;lt;TCP/IP socket failure occurred while fetching statedump over HTTP from 142374575950937656S:10.50.XX.XXX:[XXXXX,XXXXX,-1,-1,-1,-1,-1]:soa:soa_server1.&lt;br /&gt; java.io.FileNotFoundException: Response: &#39;403: Forbidden&#39; for url: &#39;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;a href=&quot;http://10.50.XXX.XXX:16101/bea_wls_cluster_internal/psquare/p2?senderNum=3&amp;amp;lastSeqNum=0&amp;amp;PeerInfo=10,3,4&amp;amp;ServerName=soa_server1&quot;&gt;&lt;span style=&quot;font-family: &#39;Andale Mono&#39;;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;http://10.50.XXX.XXX:16101/bea_wls_cluster_internal/psquare/p2?senderNum=3&amp;amp;lastSeqNum=0&amp;amp;PeerInfo=10,3,4&amp;amp;ServerName=soa_server1&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: &#39;Andale Mono&#39;;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;&#39;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; at weblogic.net.http.HttpURLConnection.getInputStream(HttpURLConnection.java:487)&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; at weblogic.cluster.HTTPExecuteRequest.connect(HTTPExecuteRequest.java:67)&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; at weblogic.cluster.HTTPExecuteRequest.run(HTTPExecuteRequest.java:83)&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; at weblogic.work.ExecuteThread.execute(ExecuteThread.java:207)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote style=&quot;display: inline !important;&quot;&gt;&lt;div style=&quot;display: inline !important;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;&lt;strong&gt;&lt;span style=&quot;font-family: &#39;Andale Mono&#39;;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;&lt;span style=&quot;font-family: Helvetica, Arial, sans-serif;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;at weblogic.work.ExecuteThread.run(ExecuteThread.java:176)&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; margin: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;So make sure that the Mutlicast address and port combination used for BAM cluster and SOA cluster is unique. There is a Multicast test utility that you can use to test communication between two instance. &lt;span style=&quot;font-size: small;&quot;&gt;More information about the utility is available&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;a href=&quot;http://download.oracle.com/docs/cd/E12840_01/wls/docs103/admin_ref/utils.html#wp1199798&quot;&gt;here&lt;/a&gt;. Also refer&amp;nbsp;&lt;a href=&quot;http://download.oracle.com/docs/cd/E11035_01/wls100/cluster/multicast_configuration.html&quot;&gt;this&lt;/a&gt;&amp;nbsp;to troubleshoot Multicast configuration.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div&gt;&lt;blockquote&gt;&lt;div style=&quot;display: inline !important;&quot;&gt;&lt;span style=&quot;font-weight: normal; font-family: &#39;andale mono&#39;, times; font-size: small;&quot;&gt;&lt;strong&gt;&lt;span style=&quot;line-height: 13px;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;export CLASSPATH=${CLASSPATH}:[bea_home]/server/lib/weblogic.jar&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;display: inline !important;&quot;&gt;&lt;span style=&quot;line-height: 13px; font-family: &#39;andale mono&#39;, times; font-size: small;&quot;&gt;&lt;span style=&quot;line-height: 13px;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;On&amp;nbsp;&amp;nbsp;Machine A:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;display: inline !important;&quot;&gt;&lt;span style=&quot;line-height: 13px; font-family: &#39;andale mono&#39;, times; font-size: small;&quot;&gt;&lt;span style=&quot;line-height: 13px;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;line-height: 13px; font-family: &#39;andale mono&#39;, times; font-size: small;&quot;&gt;java utils.MulticastTest -A [multicast address] -P [multicast port] -N TestServer1&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span style=&quot;line-height: 13px; font-family: &#39;andale mono&#39;, times; font-size: small;&quot;&gt;On Machine B:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;line-height: 13px; font-family: &#39;andale mono&#39;, times; font-size: small;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;java utils.MulticastTest -A [multicast address] -P [multicast port] -N TestServer2&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Andale Mono&#39;;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;&lt;br /&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;display: inline !important;&quot;&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; display: inline !important; margin: 0px;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; display: inline !important; margin: 0px;&quot;&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;Hope this helps!.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;display: inline !important;&quot;&gt;&lt;p style=&quot;font: normal normal normal 12px/normal Verdana; display: inline !important; margin: 0px;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;&lt;strong&gt;&lt;span style=&quot;font-family: verdana, geneva;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;br /&gt; &lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2011/07/soa-composite-deployment-oracle-soa.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-6405593460650783353</guid><pubDate>Wed, 20 Apr 2011 18:13:00 +0000</pubDate><atom:updated>2014-08-09T16:36:43.670-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">oepe</category><category domain="http://www.blogger.com/atom/ns#">osb</category><category domain="http://www.blogger.com/atom/ns#">service bus</category><category domain="http://www.blogger.com/atom/ns#">web services</category><title>OSB Project Structure</title><description>&lt;p&gt;I am doing some development with Oracle Service Bus (OSB). The primary goal is to mediate web services using OSB. Oracle does provide set of eclipse plugins to develop OSB configuration - OEPE suite. One of question that I wanted answer was what will be a good project structure to organize various components of OSB configuration. &lt;/p&gt;&lt;p&gt;Typically, OEPE plugins gives two eclipse project templates:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Oracle Service Bus Configuration Project&lt;/li&gt;&lt;li&gt;Oracle Service Bus Project&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;OSB Config project is the top level project which can include various OSB Project. A minimal OSB project includes components like business service, proxy service and WSDL. It is important to come up with a good project structure since the component shows up as is on sbconsole. You probably don&#39;t want to see all the components at same level. &lt;/p&gt;&lt;p&gt;After this exercise, I ended up with following structure of the project that I wanted to share. So here it is,&lt;/p&gt;&lt;p class=&quot;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitgOpmSkmZYamd6aoFh93kug0SshJLifZMHkj4G2Jc5oO4e6w-SaYXSZgs87MqOHt_6N1NRI6q_C9UZvsMJSI-O8I62NGg8a3c2C7K7VHz3J-DxhnLhkvU3Ock_5-vgQmY4nbPlA/&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;https:/lh4.googleusercontent.com/_Ij0FyB8Wu5Q/Ta8fTrs-sdI/AAAAAAAAAV0/sUnx7TZiUXM/s500/ScreenClip.png&quot; id=&quot;blogsy-1303327874771.2546&quot; class=&quot;aligncenter&quot; alt=&quot;&quot; width=&quot;323&quot; height=&quot;388&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The top level project - OSB Config Project - represents a business domain. So OSB configuration of all services serving a particular domain goes under that umbrella. Individual OSB Project contains mediation component for a given physical service. I used folders to group business and proxy services to allow for multiple proxy services for a given business service. Using this structure it becomes easy to manage configuration using sbconsole.&lt;/p&gt;&lt;p&gt;I ended up using the ant build script and import/export WLST script by tweaking the ones given as part of this book - &lt;a href=&quot;http://www.amazon.com/Definitive-Guide-SOA-Service-Experts/dp/1430210575/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1303324076&amp;sr=8-2&quot; target=&quot;_blank&quot; title=&quot;&quot;&gt;The definitive guide to SOA&lt;/a&gt;. The build script can export configuration from local server or workspace. Import deploys it to the target server. The import/export script also takes care of  variables that changes from environment to environment. OSB has a features to create customization XMLs. You can create customization XML per environment and run it post configuration package deployment. &lt;/p&gt;</description><link>http://blog.kartikshah.com/2011/04/osb-project-structure.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-5377468932606972946</guid><pubDate>Mon, 24 Jan 2011 05:18:00 +0000</pubDate><atom:updated>2011-01-23T23:18:27.359-06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">clojure</category><category domain="http://www.blogger.com/atom/ns#">rss</category><title>Using Clojure to work with RSS feeds</title><description>As I mentioned in my last blog entry, I am trying to learn Clojure. I think it is an interesting challenge to internalize new thinking paradigm. So following entry/code is an attempt to learn the paradigms of the language. Drop a comment, if you have any suggestion.&lt;br /&gt;&lt;br /&gt;I found that, while trying to learn new language, one of the challenge is to find interesting practice problem to solve. The practice problem which helps you understand the strength of the language. I think one such problem space Clojure&#39;s application would be interesting is parsing and data crunching.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Example Problem&lt;/span&gt;&lt;br /&gt;So the problem I picked is a simple one. I heavily use google reader and for that matter most of my web reading happens as part subscribed RSS feeds. I find myself manually filtering the feed list to suite my interest at the time. This exercise creates parser for RSS feed. This parser creates Clojure records based data structure. Once you have all the feed represented in records structure you can write variety of functions to filter the feed or even apply intelligent web algorithms.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Organization of Code&lt;/span&gt;&lt;br /&gt;I am looking for a good way to organize code in clojure. Just like Java packages, clojure has namespaces. But I have still not found a good way to organize clojure functions into files/namespaces. For now, I chose to create namespace per domain.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;rss.data.clj - Define records data structure and parser&lt;/li&gt;&lt;li&gt;rss.feed.clj - Defines functions to get feeds&lt;/li&gt;&lt;li&gt;rss.stat.clj - Defines functions to filter feeds (and may be some statistical algorithms)&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;data.clj&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;brush: clojure&quot;&gt;&lt;br /&gt;(ns rss.data&lt;br /&gt;  (:require [clojure.xml :as xml])&lt;br /&gt;  (:import  [java.io ByteArrayInputStream]))&lt;br /&gt;&lt;br /&gt;(defrecord rss-channel [title description link lastbuilddate pubdate items])&lt;br /&gt;(defrecord rss-item [title description link guid pubdate])&lt;br /&gt;&lt;br /&gt;(defn create-rss-channel [map items]&lt;br /&gt;  (let [title (:title map)&lt;br /&gt;        pubDate (:pubDate map)&lt;br /&gt;        description (:description map)&lt;br /&gt;        link (:link map)&lt;br /&gt;        lastBuildDate (:lastBuildDate map)]&lt;br /&gt;    (rss-channel. title description link lastBuildDate pubDate items)))&lt;br /&gt;&lt;br /&gt;(defn create-item [item-data]&lt;br /&gt;  (let [description (:description item-data)&lt;br /&gt;        pubDate (:pubDate item-data)&lt;br /&gt;        guid (:guid item-data)&lt;br /&gt;        link (:link item-data)&lt;br /&gt;        title (:title item-data)&lt;br /&gt;        ]&lt;br /&gt;    (rss-item. title description link guid pubDate)))&lt;br /&gt;&lt;br /&gt;(defn parse-item [item-data]&lt;br /&gt;  (create-item (zipmap (map :tag item-data) (map :content item-data))))&lt;br /&gt;&lt;br /&gt;(defn parse-items [items-data]&lt;br /&gt;  (map parse-item items-data))&lt;br /&gt;&lt;br /&gt;(defn parse-channel [channel-content]&lt;br /&gt;  (loop [x (:content channel-content)]&lt;br /&gt;    (create-rss-channel&lt;br /&gt;      (into {} (filter #(not (= :item (key %))) (zipmap (map :tag x) (map :content x))))&lt;br /&gt;      (parse-items (map :content (into [] (filter #(= :item (:tag %)) x)))))&lt;br /&gt;      ))&lt;br /&gt;&lt;br /&gt;(defn parse-rss [rss]&lt;br /&gt;  (let [rss-data (ByteArrayInputStream. (.getBytes rss &quot;UTF-8&quot;))]&lt;br /&gt;  (for [x (xml-seq (xml/parse rss-data))&lt;br /&gt;        :when (= :rss (:tag x))]&lt;br /&gt;    (map parse-channel (:content x)))))&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;feed.clj&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;brush: clojure&quot;&gt;(ns rss.feed&lt;br /&gt;  (:require [clj-http.client :as client]))&lt;br /&gt;&lt;br /&gt;(defn get-feed [url]&lt;br /&gt;  (:body (client/get url)))&lt;br /&gt;&lt;br /&gt;(defn get-feeds [urllist]&lt;br /&gt;  (pmap get-feed urllist))&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;stat.clj&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;brush: clojure&quot;&gt;(ns rss.stat)&lt;br /&gt;&lt;br /&gt;(def keywords [&quot;Clojure&quot; &quot;Groovy&quot; &quot;Python&quot;])&lt;br /&gt;&lt;br /&gt;(defn find-items [rss-item-list keyword]&lt;br /&gt;  (filter #(.contains (first (:title %)) keyword) (flatten rss-item-list)))&lt;br /&gt;&lt;br /&gt;(defn find-items-keywords [rss-item-list keyword-list]&lt;br /&gt;  (flatten (map #(find-items rss-item-list %) keyword-list)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Trying Delicious RSS&lt;br /&gt;&lt;/span&gt;Let&#39;s use RSS feed published by delicious.com. All RSS feed can found here. Let&#39;s use the feed popular which got has tag &quot;programming&quot;&lt;span style=&quot;font-weight: bold;&quot;&gt;. (&lt;/span&gt;http://feeds.delicious.com/v2/rss/popular/programming)&lt;br /&gt;&lt;pre class=&quot;brush: clojure&quot;&gt;&lt;br /&gt;user=&amp;gt; (rss.stat/find-items-keywords (map :items (flatten (rss.data/parse-rss (rss.feed/get-feed &quot;http://feeds.delicious.com/v2/rss/popular/programming&quot;)))) [&quot;Clojure&quot; &quot;Python&quot; &quot;Groovy&quot;])&lt;br /&gt;(#:rss.data.rss-item{:title [&quot;Hidden features of Python - Stack Overflow&quot;], :description nil, :link [&quot;http://stackoverflow.com/questions/101268/hidden-features-of-python/102062&quot;], :guid [&quot;http://www.delicious.com/url/16bbee33bbf4f6a03448058c5fd9f461#thaiyoshi&quot;], :pubdate [&quot;Sun, 23 Jan 2011 16:53:58 +0000&quot;]} &lt;br /&gt;#:rss.data.rss-item{:title [&quot;Writing Forwards Compatible Python Code | Armin Ronacher&#39;s Thoughts and Writings&quot;], :description nil, :link [&quot;http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/&quot;], :guid [&quot;http://www.delicious.com/url/c6fb2679bca6c193a41d92513f7edca1#papaeye&quot;], :pubdate [&quot;Sat, 22 Jan 2011 16:09:10 +0000&quot;]})&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;This one only had few links. Let&#39;s try one which has lots of items. (http://feeds.delicious.com/v2/rss/tag/programming?count=100)&lt;br /&gt;&lt;pre class=&quot;brush: clojure&quot;&gt;&lt;br /&gt;user=&amp;gt; (rss.stat/find-items-keywords (map :items (flatten (rss.data/parse-rss (rss.feed/get-feed &quot;http://feeds.delicious.com/v2/rss/tag/programming?count=100&quot;)))) [&quot;Clojure&quot; &quot;Python&quot; &quot;Groovy&quot;])&lt;br /&gt;&lt;br /&gt;(#:rss.data.rss-item{:title [&quot;The Evolution of a Python Programmer : Aleks&#39; Domain&quot;], :description nil, :link [&quot;http://metaleks.net/programming/the-evolution-of-a-python-programmer&quot;], :guid [&quot;http://www.delicious.com/url/15311aafa2207da0ffc770903091ccea#tsung&quot;], :pubdate [&quot;Mon, 24 Jan 2011 02:44:19 +0000&quot;]} &lt;br /&gt;#:rss.data.rss-item{:title [&quot;Hidden features of Python - Stack Overflow&quot;], :description nil, :link [&quot;http://stackoverflow.com/questions/101268/hidden-features-of-python/102062&quot;], :guid [&quot;http://www.delicious.com/url/16bbee33bbf4f6a03448058c5fd9f461#adharmad&quot;], :pubdate [&quot;Mon, 24 Jan 2011 02:43:07 +0000&quot;]} &lt;br /&gt;#:rss.data.rss-item{:title [&quot;PySCeS: the Python Simulator for Cellular Systems&quot;], :description nil, :link [&quot;http://pysces.sourceforge.net/index.html&quot;], :guid [&quot;http://www.delicious.com/url/40e012b894d62cd8cb9ba6b95855b868#tiguco&quot;], :pubdate [&quot;Mon, 24 Jan 2011 02:39:24 +0000&quot;]} &lt;br /&gt;#:rss.data.rss-item{:title [&quot;Hidden features of Python - Stack Overflow&quot;], :description nil, :link [&quot;http://stackoverflow.com/questions/101268/hidden-features-of-python/102062&quot;], :guid [&quot;http://www.delicious.com/url/16bbee33bbf4f6a03448058c5fd9f461#lonstile&quot;], :pubdate [&quot;Mon, 24 Jan 2011 02:24:25 +0000&quot;]} &lt;br /&gt;&lt;/pre&gt;Source Code available at GitHub (&lt;a href=&quot;https://github.com/kartikshah/rss-feeder&quot;&gt;https://github.com/kartikshah/rss-feeder&lt;/a&gt;)&lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2011/01/using-clojure-to-work-with-rss-feeds.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>5</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-1261262574066736582</guid><pubDate>Sun, 12 Dec 2010 04:26:00 +0000</pubDate><atom:updated>2012-01-16T22:14:08.767-06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">clojure</category><category domain="http://www.blogger.com/atom/ns#">compojure</category><category domain="http://www.blogger.com/atom/ns#">gae</category><category domain="http://www.blogger.com/atom/ns#">leiningen</category><title>How-To - IntelliJ Idea for Clojure/Compojure on Google App Engine</title><description>&lt;a href=&quot;http://strangeloop2010.com/&quot;&gt;StrangeLoop&lt;/a&gt; conference really spiked my interest in learning &lt;a href=&quot;http://clojure.org/&quot;&gt;Clojure&lt;/a&gt;. I wanted to find a way to do web development using &lt;a href=&quot;http://clojure.org/&quot;&gt;Clojure&lt;/a&gt;. So this entry is primarily a how-to on setup of IntelliJ Idea to do Clojure using Compojure web framework, Leiningen build tool and Google App Engine deployment environment. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 1: Download Leiningen&lt;/span&gt;&lt;br /&gt;Download &lt;a href=&quot;https://github.com/technomancy/leiningen#readme&quot;&gt;Leiningen&lt;/a&gt; script file and follow instruction to put it in PATH. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 2: Install &quot;La Clojure&quot; and &quot;Leiningen&quot; plugin for IntelliJ Idea. &lt;/span&gt;&lt;br /&gt;To do this go to Preferences -&amp;gt; Plugins. Go to &quot;Available&quot; Tab&lt;br /&gt;&lt;img src=&quot;http://kartikshah.com/images/compojure-gae-1.png&quot; style=&quot;width: 662px; height: 459px;&quot; title=&quot;La Clojure and Leiningen Plugin&quot; alt=&quot;compojure-gae-1.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 3: Setup Leiningen plugin properties&lt;/span&gt;&lt;br /&gt;To setup Leiningen plugin properties in IntelliJ click on Preferences -&amp;gt; Leiningen and give the path to the executable. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 4: Create project template&lt;/span&gt;&lt;br /&gt;Now with the installation complete, we are ready to create a new project. For now the project creation is done outside IntelliJ Idea using Lein on command line. This is the only step done outside the IntelliJ Idea. Choose the folder structure where your IntelliJ workspace is. &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $ lein new gae-cmpjr&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Created new project in: gae-cmpjr&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can see that Lein created project folder structure. In the project root it created a project.clj file used by Leiningen. Under src folder, it also created default namespace by the name of the project and created a core.clj file under it. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 5: Create project IntelliJ&lt;/span&gt;&lt;br /&gt;Let&#39;s create IntelliJ Project, even though project structure exists pick the same folder path that you selected in step 4. &lt;br /&gt;&lt;ul&gt;&lt;li&gt;File -&amp;gt; Project New... and select project from scratch&lt;/li&gt;&lt;li&gt;Select both GAE and Clojure. Provide the path to the appengine sdk&lt;/li&gt;&lt;/ul&gt;&lt;img src=&quot;http://kartikshah.com/images/compojure-gae-2.png&quot; style=&quot;width: 618px; height: 518px;&quot; title=&quot;IntelliJ Setup &quot; alt=&quot;compojure-gae-2.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;Now basic setup for the project is done. You can browse the project files using IntelliJ. (Biggest benefit of La Clojure is it auto-inserts and matches brackets for very &quot;brackety language&quot; :-)) &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 6: Setup Leiningen to run from IntelliJ&lt;/span&gt;&lt;br /&gt;To setup Leiningen from IntelliJ, click on Leiningen tool window. (Window -&amp;gt; Tool Windows -&amp;gt; Leiningen) &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 7: Setup web development libraries&lt;/span&gt;&lt;br /&gt;Setup the project to include Compojure and Ring libraries for development. &lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;project.clj&lt;/span&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&lt;br /&gt;(defproject gae-cmpjr &quot;1.0.0-SNAPSHOT&quot;&lt;br /&gt;&amp;nbsp; :description &quot;Example for Compojure on GAE using IntelliJ&quot;&lt;br /&gt;&amp;nbsp; :namespaces [gae-cmpjr.core] &lt;br /&gt;&amp;nbsp; :dependencies [[compojure &quot;0.4.0-SNAPSHOT&quot;]&lt;br /&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;&amp;nbsp;&amp;nbsp; [ring/ring-servlet &quot;0.2.1&quot;]]&lt;br /&gt;&amp;nbsp; :dev-dependencies [[leiningen/lein-swank &quot;1.2.0-SNAPSHOT&quot;]]&lt;br /&gt;&amp;nbsp; :compile-path &quot;web/WEB-INF/classes&quot;&lt;br /&gt;&amp;nbsp; :library-path &quot;web/WEB-INF/lib&quot;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;core.clj&lt;/span&gt;&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&lt;br /&gt;(ns gae-cmpjr.core&lt;br /&gt;&amp;nbsp; (:gen-class :extends javax.servlet.http.HttpServlet)&lt;br /&gt;&amp;nbsp; (:use compojure.core&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ring.util.servlet)&lt;br /&gt;&amp;nbsp; (:require [compojure.route :as route]))&lt;br /&gt;&lt;br /&gt;(defroutes hello&lt;br /&gt;&amp;nbsp; (GET &quot;/&quot; [] &quot;&amp;lt;h1&amp;gt;Hello World Wide Web!&amp;lt;/h1&amp;gt;&quot;)&lt;br /&gt;&amp;nbsp; (route/not-found &quot;Page not found&quot;))&lt;br /&gt;&lt;br /&gt;(defservice hello)&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 8:&amp;nbsp; GAE setup&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;web.xml&lt;/span&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;web-app xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; version=&quot;2.5&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;display-name&amp;gt;Compojure on GAE using IntelliJ&amp;lt;/display-name&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;servlet&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;servlet-name&amp;gt;hello&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;servlet-class&amp;gt;gae_cmpjr.core&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/servlet&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;servlet-name&amp;gt;hello&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;url-pattern&amp;gt;/&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;&amp;lt;/web-app&amp;gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;appengine-web.xml&lt;/span&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;&lt;br /&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;appengine-web-app xmlns=&quot;http://appengine.google.com/ns/1.0&quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;application&amp;gt;compgae&amp;lt;/application&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;version&amp;gt;v0-2&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;/appengine-web-app&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 9: Compile and Build war &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;From the Leiningen Tool window in Idea run following commands.&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;margin-left: 40px;&quot;&gt;&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;lein clean&lt;br /&gt;lein deps &lt;br /&gt;lein compile &lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 10: Run locally &lt;/span&gt;&lt;br /&gt;To locally run click on already create &quot;Run Configuration&quot; &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 11: To upload application to appengine&lt;/span&gt;&lt;br /&gt;Tools -&amp;gt; Upload Appengine application &lt;br /&gt;&lt;img src=&quot;http://kartikshah.com/images/compojure-gae-4.png&quot; style=&quot;width: 349px; height: 245px;&quot; title=&quot;Sample Run&quot; alt=&quot;compojure-gae-4.png&quot; /&gt;&lt;br /&gt;&lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2010/12/how-to-intellij-idea-for.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-8950846180986694124</guid><pubDate>Sun, 26 Sep 2010 04:11:00 +0000</pubDate><atom:updated>2014-08-09T16:46:00.093-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dsl</category><category domain="http://www.blogger.com/atom/ns#">gep3</category><category domain="http://www.blogger.com/atom/ns#">groovy</category><category domain="http://www.blogger.com/atom/ns#">java</category><title>Revisiting JMX DSL with Groovy GEP3</title><description>In one of the &lt;a href=&quot;http://blog.kartikshah.info/2010/02/groovy-dsl-jmx-reporting.html&quot;&gt;previous blog post&lt;/a&gt;, I experimented with a &lt;a href=&quot;http://blog.kartikshah.info/2010/02/groovy-dsl-jmx-reporting.html&quot;&gt;sample DSL for JMX reporting using Jfree chart&lt;/a&gt;. Groovy 1.8.2 (Beta) has introduced command expression language. This &lt;a href=&quot;http://docs.codehaus.org/display/GroovyJSR/GEP+3+-+Command+Expression+based+DSL&quot;&gt;GEP-3&lt;/a&gt; essentially allows you to create command expression language which can further simplify language of DSL. The primary use of this is to aid in writing impromptu scripts to visually demo various MBean values. In this example we will see bar charts for module processing time for all web modules. &lt;br /&gt;&lt;br /&gt;Command expression language allows you to alternate method name and parameter for even number of argument&lt;br /&gt;e.g. &lt;br /&gt;foo a1 a2 a3 a4 a5. Foo(a1).a2(a3).a4(a5)&lt;br /&gt;You can find more example and explanation on &lt;a href=&quot;http://docs.codehaus.org/display/GroovyJSR/GEP+3+-+Command+Expression+based+DSL&quot;&gt;GEP-3 page&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Revisiting &lt;a href=&quot;http://blog.kartikshah.info/2010/02/groovy-dsl-jmx-reporting.html&quot;&gt;JMX example&lt;/a&gt; so that I can simplify the language as &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;server.url &quot;service:jmx:rmi://localhost/jndi/rmi://localhost:1090/jmxconnector&quot; query &quot;jboss.web:*&quot; filter &quot;j2eeType=WebModule&quot;&lt;br /&gt;def filteredModules = server.filteredModules&lt;br /&gt;&lt;br /&gt;chart.type &quot;Bar&quot; modules filteredModules title &quot;Module Processing Time&quot; width 1200 height 700 refresh 500 attributes params labels graphLabels&lt;br /&gt;chart.show()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let&#39;s look at the supporting code. &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;import org.jfree.chart.ChartFactory&lt;br /&gt;import groovy.swing.SwingBuilder&lt;br /&gt;&lt;br /&gt;import org.jfree.data.category.DefaultCategoryDataset&lt;br /&gt;import org.jfree.chart.plot.PlotOrientation as Orientation&lt;br /&gt;import javax.swing.WindowConstants as WC&lt;br /&gt;import javax.management.ObjectName&lt;br /&gt;import javax.management.remote.JMXConnectorFactory&lt;br /&gt;import javax.management.remote.JMXServiceURL as JmxUrl&lt;br /&gt;import javax.naming.Context&lt;br /&gt;&lt;br /&gt;class Chart {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def chartModules&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def chartType&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def chartAttributes = {m -&amp;gt; [m.processingTime, m.path]}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def chartLabels =[&quot;Time per Webapp&quot;, &quot;Webapp&quot;, &quot;Time&quot;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def chartOptions = [false, true, true]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def windowTitle&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def w&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def h&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def refreshRate&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def orientation = &quot;VERTICAL&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def dataset&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def modules(m) {&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; chartModules = m&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def type(type) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; chartType = type&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def attributes(attr) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; chartAttributes = attr&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def labels (lbls) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; chartLabels = lbls&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def options (opts) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; chartOptions = opts&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def title (title) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; windowTitle = title&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def width(width) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; w = width&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def height(height) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; h = height&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def refresh(r) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; refreshRate = r&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void show(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; switch(chartType){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; case &quot;Bar&quot;: drawBarChart(); break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; default: break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void drawBarChart(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; calculateData()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def chart = ChartFactory.createBarChart(*chartLabels, dataset, Orientation.&quot;${orientation}&quot;, *chartOptions)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def swing = new SwingBuilder()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def frame = swing.frame(title:windowTitle, defaultCloseOperation:WC.EXIT_ON_CLOSE){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; panel(id:&#39;canvas&#39;) {rigidArea(width:w, height:h)}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; while(true){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; calculateData()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; chart.fireChartChanged()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; frame.pack()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; frame.show()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; chart.draw(swing.canvas.graphics, swing.canvas.bounds)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; sleep(refreshRate)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void calculateData(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def newDataset = new DefaultCategoryDataset()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; chartModules.each{ m -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; def dsCall = chartAttributes.call(m)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; newDataset.addValue dsCall[0], 0, dsCall[1]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; this.dataset = newDataset&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class Server {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def server&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def queryObjects&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def moduleFilter&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def filteredModules&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def url(serverName){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; server = JMXConnectorFactory.connect(new JmxUrl(serverName)).MBeanServerConnection&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def query (queryString) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; queryObjects = new ObjectName(queryString)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def filter (filterString) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; String[] allNames = server.queryNames(queryObjects, null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; filteredModules = allNames.findAll { name -&amp;gt; name.contains(filterString)}.collect { new GroovyMBean(server, it)}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;server = new Server()&lt;br /&gt;chart = new Chart()&lt;br /&gt;params = {m -&amp;gt; [m.processingTime, m.path]}&lt;br /&gt;graphLabels = [&quot;Time per Webapp&quot;, &quot;Webapp&quot;, &quot;Time&quot;]&lt;br /&gt;&lt;br /&gt;server.url &quot;service:jmx:rmi://localhost/jndi/rmi://localhost:1090/jmxconnector&quot; query &quot;jboss.web:*&quot; filter &quot;j2eeType=WebModule&quot;&lt;br /&gt;def filteredModules = server.filteredModules&lt;br /&gt;&lt;br /&gt;chart.type &quot;Bar&quot; modules filteredModules title &quot;Module Processing Time&quot; width 1200 height 700 refresh 500 attributes params labels graphLabels&lt;br /&gt;chart.show()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Problems&lt;/span&gt; &lt;span style=&quot;font-weight: bold;&quot;&gt;faced&lt;/span&gt;&lt;br /&gt;For some reason with the current beta build I couldn&#39;t do arrays or closures inline. so I had to put them as separate variables. I do not think it is by design and as 1.8.X comes close to release these wrinkles will be worked out. &lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2010/09/revisiting-jmx-dsl-with-groovy-gep3.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-800245131066444293</guid><pubDate>Thu, 01 Apr 2010 04:46:00 +0000</pubDate><atom:updated>2014-08-09T16:38:46.469-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">data-service</category><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">soa</category><title>Data as Service - Thoughts</title><description>I am exploring multiple ways to expose data as a service. Let&#39;s take a brief look at problem description. You have a central data repository which acts as source of truth for multiple supporting application. These supporting applications usually reads data and manipulate/transform it and do what it needs to do with it. &lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.kartikshah.com/images/data-as-a-service.png&quot; style=&quot;margin: 0px auto 10px; display: block; text-align: center; width: 569px; height: 217px;&quot; title=&quot;Typical Scenario&quot; alt=&quot;data-as-a-service.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;This is not very atypical scenario. In most of the organization you will have a central application - usually of the shelf product with specific customization. e.g. ERP systems, Billing systems, CRM systems etc. The data store supporting this application is not flexible to customization. You will also find supporting applications for custom needs of organization to use the central data store. In usual scenarios this application will be handling this via direct read from central data store - potentially giving way to duplication of effort to manage this objects. &lt;br /&gt;&lt;br /&gt;These problems have been solved in multiple ways. &lt;br /&gt;&lt;ol&gt;&lt;li&gt;Allow each individual supporting application to access data directly or indirectly through data warehouses &lt;/li&gt;&lt;li&gt;Expose the catalog of finely-tuned queries expose by the supporting application as web services. &lt;/li&gt;&lt;li&gt;Define organization wide data directory containing well defined business entities/objects and expose web services to retrieve defined entities. &lt;/li&gt;&lt;/ol&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Types of Services &lt;/span&gt;&lt;br style=&quot;font-weight: bold;&quot; /&gt;We can classify this data services in multiple categories&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Data-Read Services&lt;/span&gt; - These are plain and simple data read or data lookup services. This services provide only minor transformation like column renames, etc&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Transformation Services&lt;/span&gt; - These services provide some transformation of data. It operates on the column performs operation like truncation, concatenation, etc. &lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Filtering Services&lt;/span&gt; - These services allows opportunity to filter data based on input conditions. e.g provide active accounts, provide prospect accounts, etc. &lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Aggregation Services&lt;/span&gt; - These services provides performs certain aggregation function. e.g. sales by region, accounts by regions, etc. Though this logic could have served better purpose if kept in application, there are some performance benefits to do this in the data store layer.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Define Business Entities data dictionary&lt;/span&gt;&lt;br /&gt;First and foremost identify organization wide data dictionary for the domain. This data dictionary is the definition of entities that applications needs to use. So there is not duplication. It also reduces confusion. For example, an entity named BillingAccount will mean the billing account for any application using it. This solves a larger problem, in the scenario where the supporting applications use the data directory it defines these central entities in multiple ways. So over time the definition of the same thing becomes convoluted. e.g. account number for application A is 10 digits and same for application b is first 8 digits of that. This results in duplication of data that can not inter operate. Defining a central data dictionary and allowing exchange of that in that contract helps avoid this problem. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Logical Representation&lt;/span&gt;&lt;br /&gt;In most scenario the data store that comes bundled with the product is really generic so that product can be customized to different business. eg. ACCTPF having fields like ACCTPFNO, ACCTPFHONO, etc. One side effect can be seen on naming convention of entities and its properties. They are wierdly named and does not make any sense without actually looking at product documentation. My take is that some naming transformation is required. This can be done by &quot;select as&quot; queries or actually overlaying a logical data model on top of the existing one. Of course after performance consideration. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Expose as Web Service&lt;/span&gt;&lt;br /&gt;Once you have the logical representation any of following two options can be followed &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Write Select queries and expose them as either SOAP/REST web services &lt;/li&gt;&lt;li&gt;If select queries does not provide necessary transformation/aggregation, write db procedures and expose them as a service.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;One of the sub variation of this scenario is to use DB specific data structures. (In case of Oracle, use oracle&#39;s user defined types). Performance consideration is essential because remember these services may very well be the most atomic activity overarching application will perform and it is essential that each data read is trivial and inexpensive. &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;Just some thoughts...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2010/03/data-as-service-thoughts.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-4574972394943063954</guid><pubDate>Wed, 17 Mar 2010 04:05:00 +0000</pubDate><atom:updated>2014-08-09T16:46:00.078-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">activex</category><category domain="http://www.blogger.com/atom/ns#">groovy</category><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">outlook</category><category domain="http://www.blogger.com/atom/ns#">scriptom</category><title>Using Groovy Scriptom to report on Outlook</title><description>As with most work places, I use MS Outlook Calendar at work for meetings, calendars, etc. With Outlook 2007 you have capability to categorize each meeting/time block that you have on your calendar. So you can classify each meeting as either design, architecture, learning, recurring, etc. Using &lt;a href=&quot;http://groovy.codehaus.org/COM+Scripting&quot;&gt;Groovy Scriptom&lt;/a&gt; module you can do what you would usually do using VBScript. Scriptom allows you to use ActiveX windows components from Groovy. Needless to say this will only work on windows platform. &lt;br /&gt;&lt;br /&gt;I used the &lt;a href=&quot;http://groovy.codehaus.org/COM+Scripting&quot;&gt;scriptom&lt;/a&gt; to report on how I am spending my time. (ah.. have to fill those time sheet) Using Swingbuilder and JFreeChart, I threw in this simple script. You will need to setup dependency exactly as described on the &lt;a href=&quot;http://groovy.codehaus.org/COM+Scripting#COMScripting-AddingScriptomtoaMavenProject&quot;&gt;help page here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;import org.codehaus.groovy.scriptom.ActiveXObject&lt;br /&gt;import org.jfree.chart.ChartFactory &lt;br /&gt;import javax.swing.WindowConstants as WC&lt;br /&gt;&lt;br /&gt;def outlook = new ActiveXObject(&quot;Outlook.Application&quot;)&lt;br /&gt;def namespace = outlook.GetNamespace(&quot;MAPI&quot;)&lt;br /&gt;def calFolder = namespace.GetDefaultFolder(9)&lt;br /&gt;def myItems = calFolder.Items&lt;br /&gt;&lt;br /&gt;def today = new Date()&lt;br /&gt;startWeek = today - 7 &lt;br /&gt;endWeek = today + 7&lt;br /&gt;def categoryMap = [:]&lt;br /&gt;&lt;br /&gt;for (i in 1..myItems.Count.value) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; def currentMeeting = myItems.Item(i)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (currentMeeting.Start &amp;gt;= startWeek &amp;amp;&amp;amp; currentMeeting.Start &amp;lt;= endWeek) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; println &quot;Subject: &quot; + currentMeeting.Subject.value&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; println &quot;Category: &quot; + currentMeeting.Categories&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; println &quot;Duration: &quot; + currentMeeting.Duration.value&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; category = currentMeeting.Categories&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; durationValue = currentMeeting.Duration.value&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; def value = categoryMap.get(category)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = value?value:0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; def newValue = value + durationValue&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; categoryMap.put(category,newValue);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def swing = new groovy.swing.SwingBuilder()&lt;br /&gt;def titleString = &#39;Time Outlook: &#39; + String.format(&#39;%tm/%&amp;lt;td/%&amp;lt;tY&#39;, startWeek) + &quot;-&quot; + String.format(&#39;%tm/%&amp;lt;td/%&amp;lt;tY&#39;, endWeek)&lt;br /&gt;def frame = swing.frame(title:titleString,&lt;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; defaultCloseOperation:WC.EXIT_ON_CLOSE,&lt;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; size:[800,600], locationRelativeTo: null) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; borderLayout()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; panel(id:&#39;canvas&#39;) { rigidArea(width:700, height:500) }&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;def bounds = new java.awt.Rectangle(0,0, 700,500).bounds&lt;br /&gt;def piedata = new org.jfree.data.general.DefaultPieDataset()&lt;br /&gt;for(entry in categoryMap)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; piedata.setValue entry.key + &quot; = &quot; + entry.value, entry.value&lt;br /&gt;}&lt;br /&gt;def options = [false, true, false]&lt;br /&gt;def chart = ChartFactory.createPieChart(titleString, piedata, *options)&lt;br /&gt;chart.backgroundPaint = java.awt.Color.white&lt;br /&gt;frame.pack()&lt;br /&gt;frame.show()&lt;br /&gt;chart.draw(swing.canvas.graphics, bounds)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Simple enough script... It gets the ActiveXObject for Outlook application. Then from namespace it gets calendarFolder (constant 9). You can find out more about &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa831898%28office.10%29.aspx&quot;&gt;constant here&lt;/a&gt;. calFolder contains all the meeting appointmentItems. Once you get to the appointmentItem you can ask for the properties using groovy dot-notation. &lt;br /&gt;&lt;br /&gt;Here is the snapshot of the output&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://kartikshah.info/images/groovy-scriptom-outlook.png&quot; style=&quot;width: 530px; height: 393px;&quot; title=&quot;Groovy Scriptom &quot; alt=&quot;groovy-scriptom-outlook.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2010/03/using-groovy-scriptom-to-report-on.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-1150295499101921974</guid><pubDate>Mon, 01 Mar 2010 05:59:00 +0000</pubDate><atom:updated>2014-08-09T16:46:00.063-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ast-transformation</category><category domain="http://www.blogger.com/atom/ns#">dsl</category><category domain="http://www.blogger.com/atom/ns#">groovy</category><category domain="http://www.blogger.com/atom/ns#">java</category><title>Revisit Jmx Groovy DSL - Using AstTransformation</title><description>In the &lt;a href=&quot;http://blog.kartikshah.info/2010/02/groovy-dsl-jmx-reporting.html&quot;&gt;previous blog entry&lt;/a&gt;, we created Jmx Charting DSL. Let visit some aspects of creating DSL using groovy. &lt;br /&gt;&lt;br /&gt;In the previous blog example we created DSL using &lt;a href=&quot;http://groovy.codehaus.org/api/groovy/lang/ExpandoMetaClass.html&quot;&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;ExpandoMetaClass&lt;/span&gt;&lt;/a&gt;. Users will define the script starting with node &lt;span style=&quot;font-style: italic;&quot;&gt;jmx&lt;/span&gt; { }. With the use of ExpandoMetaClass we added the dynamic method which in turn delegated to class JmxClosureDelegate. Here is the snippet of the code. &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;static void runEngine(File dsl){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Script dslScript = new GroovyShell().parse(dsl.text)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dslScript.metaClass = createExpandoMetaClass(dslScript.class, {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExpandoMetaClass emc -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emc.jmx = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Closure cl -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.delegate = new JmxClosureDelegate()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.resolveStrategy = Closure.DELEGATE_FIRST&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; })&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dslScript.run()&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;/pre&gt;What we essentially did here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Using GroovyShell it parses the script file passed as input. &lt;/li&gt;&lt;li&gt;Defines the ExpandoMetaClass and adds method by name &quot;jmx&quot; having closure as parameter. &lt;/li&gt;&lt;/ul&gt; So the script file you wrote gets a dynamic method injected into it using ExpandoMetaClass. This happens at runtime. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Getting rid of the Commas&lt;br /&gt;&lt;/span&gt;The problem with creating methods with two arguments is that you have to specify commas between them. For example, &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; server &quot;nameofserver&quot;, {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&lt;/pre&gt;Undoubtedly commas clutter the langauge grammer. To get rid of the commas we used trick provided on Groovy users list. &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;//To avoid using &quot;,&quot; between String and Closure argument&amp;nbsp; &lt;br /&gt;&amp;nbsp; def methodMissing(String name, args) {&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return [name, args[0]]&amp;nbsp; &lt;br /&gt;&amp;nbsp; }&amp;nbsp; &lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Using AstTransformation&lt;/span&gt;&lt;br /&gt;Now lets explore a different possibility. You can achieve similar result using AstTransformation at compile time. The goal remains the same and that is to add method with name &quot;jmx&quot; with closure parameter. &lt;br /&gt;&lt;br /&gt;First we will define the annotation.&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;//import statements skipped for brevity&lt;br /&gt;@Retention(RetentionPolicy.SOURCE)&lt;br /&gt;@Target([ElementType.METHOD])&lt;br /&gt;@GroovyASTTransformationClass([&quot;info.kartikshah.jmx.ast.JmxDslTransformation&quot;])&lt;br /&gt;public @interface UseJmxDsl {}&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Transformation Class&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This transformation class needs to perform two activities:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Add method &lt;span style=&quot;font-style: italic;&quot;&gt;jmx(Closure cl) &lt;/span&gt;method&lt;/li&gt;&lt;li&gt;Invoke the script method being defined&lt;/li&gt;&lt;/ul&gt;We need to generate AST statements for following snippet of code. &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jmx = {&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Closure cl -&amp;gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.delegate = new JmxClosureDelegate()&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.resolveStrategy = Closure.DELEGATE_FIRST&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl()&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp; &lt;br /&gt;&lt;/pre&gt;We will use AstBuilder&#39;s buildFromSpec option to generate it. (AstBuilders added with Groovy 1.7 definitely makes generating statement structure relatively easy and clutter free. Not to mention it is also an example of DSL added to the groovy language :-) ) &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)&lt;br /&gt;class JmxDslTransformation implements ASTTransformation {&lt;br /&gt;&amp;nbsp; static int PUBLIC = 1&lt;br /&gt;&amp;nbsp; static int STATIC = 8&lt;br /&gt;&lt;br /&gt;&amp;nbsp; void visit(ASTNode[] astNodes, SourceUnit sourceUnit) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Add method jmx(Closure cl)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ClassNode declaringClass = astNodes[1].declaringClass&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MethodNode jmxMethod = makeMethod()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; declaringClass.addMethod(jmxMethod)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Insert method call inside run method of the script class&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MethodNode annotatedMethod = astNodes[1]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;MethodNode&amp;gt; allMethods = sourceUnit.AST?.classes*.methods.flatten()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MethodNode runMethod = allMethods.find{ MethodNode method -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; method.name == &quot;run&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; List existingStatements = runMethod.getCode().getStatements()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; existingStatements.add(0, createMethodCall(annotatedMethod))&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; Statement createMethodCall(MethodNode methodNode){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def statementAst = new AstBuilder().buildFromSpec {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; expression{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; methodCall {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; variable &quot;this&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; constant methodNode.name&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; argumentList {}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Statement stmt = statementAst[0]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stmt&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; MethodNode makeMethod() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def ast = new AstBuilder().buildFromSpec {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; method(&#39;jmx&#39;, PUBLIC | STATIC, Void.TYPE) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; parameters {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; parameter &#39;cl&#39;: Closure.class&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; exceptions {}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; block {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; expression {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; binary {&lt;br /&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; property {&lt;br /&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;&amp;nbsp; variable &quot;cl&quot;&lt;br /&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;&amp;nbsp; constant &quot;delegate&quot;&lt;br /&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; }&lt;br /&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; token &quot;=&quot;&lt;br /&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; constructorCall(JmxClosureDelegate.class) {&lt;br /&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;&amp;nbsp; argumentList()&lt;br /&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; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; expression {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; binary {&lt;br /&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; property {&lt;br /&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;&amp;nbsp; variable &quot;cl&quot;&lt;br /&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;&amp;nbsp; constant &quot;resolveStrategy&quot;&lt;br /&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; }&lt;br /&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; token &quot;=&quot;&lt;br /&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; property {&lt;br /&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;&amp;nbsp; classExpression Closure&lt;br /&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;&amp;nbsp; constant &quot;DELEGATE_FIRST&quot;&lt;br /&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; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; expression {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; methodCall {&lt;br /&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; variable &quot;cl&quot;&lt;br /&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; constant &quot;call&quot;&lt;br /&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; argumentList {}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MethodNode jmxMethod = ast[0]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; jmxMethod&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Why use AstTransformation?&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;The question is why one would want to use AstTransformation when you can add method during runtime. For the given scenario, it is correct that you want to stick with adding method runtime. But consider scenario where you want to &lt;span style=&quot;font-weight: bold;&quot;&gt;&quot;redefine&quot; meaning of Groovy&#39;s syntax&lt;/span&gt;. For example like following &lt;span style=&quot;font-weight: bold;&quot;&gt;imaginary script&lt;/span&gt; using Statement Labels to add more readability to your DSL syntax. &lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;@info.kartikshah.jmx.ast.UseJmxDsl&lt;br /&gt;runDsl () {&lt;br /&gt;&amp;nbsp; jmx {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; setup:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; server &quot;service:jmx:rmi://localhost/jndi/rmi://localhost:1090/jmxconnector&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; query &quot;jboss.web:*&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; findAll &quot;j2eeType=Servlet&quot;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; draw:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; chart {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; chartType=&quot;Bar&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; attributes={m-&amp;gt; [m.loadTime, m.objectName.find(&quot;name=([^,]*)&quot;){it[1]}]}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; labels=[&quot;Load Time per Servlet&quot;, &quot;Servlet&quot;, &quot;Time&quot;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; options=[false, true, true]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; windowTitle=&quot;JBoss Servlet Processing Time&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; width=1200&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; height=700&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; orientation=&quot;HORIZONTAL&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; refreshRate=5000&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; show()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Spock Framework does similar twist by redefining meaning of existing construct. &lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;With this type of language structure you will end up defining your own &lt;span style=&quot;font-weight: bold;&quot;&gt;set of keywords&lt;/span&gt;, &lt;span style=&quot;font-weight: bold;&quot;&gt;supporting parser&lt;/span&gt; and &lt;span style=&quot;font-weight: bold;&quot;&gt;few AstTransformation&lt;/span&gt; to change the meaning of existing Groovy Syntax. &lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2010/02/revisit-jmx-groovy-dsl-using.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-4378577077693774861</guid><pubDate>Wed, 17 Feb 2010 04:30:00 +0000</pubDate><atom:updated>2014-08-09T16:46:00.074-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dsl</category><category domain="http://www.blogger.com/atom/ns#">groovy</category><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">jfreechart</category><category domain="http://www.blogger.com/atom/ns#">jmx</category><category domain="http://www.blogger.com/atom/ns#">swingbuilder</category><title>A Groovy DSL - JMX Reporting</title><description>In &lt;a href=&quot;http://blog.kartikshah.info/2009/06/jmx-groovy-jfreechart-and-swing.html&quot;&gt;previous blog example&lt;/a&gt;, using JFreeChart, JMX and SwingBuilder we came up with dashboard type utility. With this post we will explore how to write small DSL which will allow to report on JMX using reporting charts. The DSL will using Groovy&#39;s SwingBuilder to draw JFree Chart to report on various MBeans. This type DSL can be used to write small scripts to monitor behavioral aspect of application server (or any JMX based application).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Simple DSL&lt;/span&gt;&lt;br /&gt;First we will chart out how we want our domain language to look like. DSL syntax can be done multiple ways. It is necessary that you play with the syntax to come up with one that works for the scenario. For our example, here is the first cut that we will use. &lt;br /&gt;&lt;br /&gt;Essentially, the script reports processing time of all web modules defined on (in this example - JBoss) application server using Bar Chart.&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;jmx {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; server &quot;service:jmx:rmi://localhost/jndi/rmi://localhost:1090/jmxconnector&quot; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; query &quot;jboss.web:*&quot; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; findAll &quot;j2eeType=WebModule&quot; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; chart{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; chartType=&quot;Bar&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; attributes={m-&amp;gt; [m.processingTime, m.path]}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; labels=[&quot;Time per Webapp&quot;, &quot;Webapp&quot;, &quot;Time&quot;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; options=[false, true, true]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; windowTitle=&quot;JBoss Module Processing Time&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; width=1200&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; height=700&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; refreshRate=5000&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; show()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Other Use cases&lt;/span&gt;&lt;br /&gt;Target users for this DSL are system administrators who can write simple scripts to monitor and/or report on various aspects of app server instances graphically. &lt;br /&gt;&lt;br /&gt;Some other use cases for this type of DSL&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Compare Processing Time of Web Application&lt;/li&gt;&lt;li&gt;Compare Load Time of Servlets&lt;/li&gt;&lt;li&gt;Compare Response Time&lt;/li&gt;&lt;li&gt;Compare memory usage &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Compare total requests&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;DSL Engine&lt;/span&gt;&lt;br /&gt;With Groovy there are multiple ways to write domain specific language as described in &lt;a href=&quot;http://docs.codehaus.org/display/GROOVY/Writing+Domain-Specific+Languages&quot;&gt;groovy documentation here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We will use nested closure approach. More information about &lt;a href=&quot;http://www.martinfowler.com/dslwip/NestedClosure.html&quot;&gt;nested closure here.&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Here we use ExpandoMetaClass and series of Delegate classes to handle each closure. In the sample script above read each node (eg. jmx, server, query) as a dynamic method call with one or two arguments. For example jmx has a string argument followed by closure argument. String argument is we just store in instance variable. For closure argument we delegate the handling to separate Delegate Class. We follow the same pattern for the rest of the nested nodes.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;First up Engine&lt;/span&gt;&lt;br /&gt;This is the main class for the DSL. It gets the file passed as command args and pass it to GroovyShell to create Script object. It uses ExpandoMetaClass to dynamically add methods/closure. It add adds jmx closure and sets properties for handling closure. &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;class JmxReportingDslEngine {&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; static main(String[] args){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(args.length != 1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; println(&quot;Usage: JmxReportingDslEngine &amp;lt;ScriptFileName&amp;gt;&quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; runEngine(new File(args[0]))&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; static void runEngine(File dsl){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Script dslScript = new GroovyShell().parse(dsl.text)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dslScript.metaClass = createExpandoMetaClass(dslScript.class, {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExpandoMetaClass emc -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; emc.jmx = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Closure cl -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.delegate = new JmxClosureDelegate()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.resolveStrategy = Closure.DELEGATE_FIRST&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; })&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dslScript.run()&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; static ExpandoMetaClass createExpandoMetaClass(Class clazz, Closure cl){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ExpandoMetaClass emc = new ExpandoMetaClass(clazz, false)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl(emc)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; emc.initialize()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return emc&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;Delegates &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Next up we write series of Delegate Class responsible for handling each node of the language. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;JMXClosureDelegate&lt;/span&gt;&lt;br /&gt;This handles closure passed to jmxtag. It instantiates MBeanServerConnection and passes the reference down to the delegate chain. &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;class JmxClosureDelegate {&lt;br /&gt;  //To avoid using &quot;,&quot; between String and Closure argument&lt;br /&gt;&amp;nbsp; def methodMissing(String name, args) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return [name, args[0]]&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; void server(param){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def (serverUrl, cl) = param&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def server = JMXConnectorFactory.connect(new JmxUrl(serverUrl),env).MBeanServerConnection&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.delegate = new JmxServerClosureDelegate(server)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.resolveStrategy = Closure.DELEGATE_FIRST&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl()&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;JMXServerClosureDelegate&lt;/span&gt;&lt;br /&gt;This delegate handles closure passed to server tag. &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;class JmxServerClosureDelegate {&lt;br /&gt;&amp;nbsp; def server&lt;br /&gt;&amp;nbsp; JmxServerClosureDelegate(server){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.server = server&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; def methodMissing(String name, args) {&lt;br /&gt;&amp;nbsp;&amp;nbsp; return [name, args[0]]&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; void query(param){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def (objectName, cl) = param&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def query = new ObjectName(objectName)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; String[] allNames = server.queryNames(query, null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.delegate = new JmxQueryClosureDelegate(allNames, server)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.resolveStrategy = Closure.DELEGATE_FIRST&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl()&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;JmxQueryClosureDelegate &lt;/span&gt;&lt;br /&gt;and so on...&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;class JmxQueryClosureDelegate {&lt;br /&gt;&amp;nbsp; def allNames&lt;br /&gt;&amp;nbsp; def server&lt;br /&gt;&amp;nbsp; JmxQueryClosureDelegate(allNames, server){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.allNames = allNames&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.server = server&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; def methodMissing(String name, args) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return [name, args[0]]&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; void findAll(param){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def (filter, cl) = param&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def modules = allNames.findAll{ name -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name.contains(filter)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }.collect{ new GroovyMBean(server, it) }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.delegate = new JmxFindAllClosureDelegate(modules)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.resolveStrategy = Closure.DELEGATE_FIRST&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl()&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;JmxFindAllClosureDelegate &lt;/span&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;class JmxFindAllClosureDelegate {&lt;br /&gt;&amp;nbsp; def modules&lt;br /&gt;&amp;nbsp; JmxFindAllClosureDelegate(modules){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.modules = modules&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; void chart(Closure cl){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.delegate = new ChartDelegate(modules)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl.resolveStrategy = Closure.DELEGATE_FIRST&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cl()&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;ChartDelegate &lt;/span&gt;&lt;br /&gt;This class &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Creates the dataset from the MBean values&lt;/li&gt;&lt;li&gt;Creates the chart with the dataset values&lt;/li&gt;&lt;li&gt;Creates the external frame using SwingBuilder&lt;/li&gt;&lt;/ul&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;class ChartDelegate {&lt;br /&gt;&lt;br /&gt;&amp;nbsp; def modules&lt;br /&gt;&amp;nbsp; def chartType&lt;br /&gt;&amp;nbsp; def attributes&lt;br /&gt;&amp;nbsp; def labels&lt;br /&gt;&amp;nbsp; def options&lt;br /&gt;&amp;nbsp; def windowTitle&lt;br /&gt;&amp;nbsp; def width&lt;br /&gt;&amp;nbsp; def height&lt;br /&gt;&amp;nbsp; def refreshRate&lt;br /&gt;&amp;nbsp; def orientation = &quot;VERTICAL&quot;&lt;br /&gt;&amp;nbsp; def dataset&lt;br /&gt;&amp;nbsp; ChartDelegate(modules){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.modules = modules&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; void show(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; switch(chartType){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case &quot;Bar&quot;: drawBarChart(); break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //TODO:Add more chart types&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; default: break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; void drawBarChart(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; calculateData()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def chart = ChartFactory.createBarChart(*labels, dataset, Orientation.&quot;${orientation}&quot;, *options)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def swing = new SwingBuilder()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def frame = swing.frame(title:windowTitle, defaultCloseOperation:WC.EXIT_ON_CLOSE){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; panel(id:&#39;canvas&#39;) {rigidArea(width:width, height:height)}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(true){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; calculateData()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; chart.fireChartChanged()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; frame.pack()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; frame.show()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; chart.draw(swing.canvas.graphics, swing.canvas.bounds)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sleep(refreshRate)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; void calculateData(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def newDataset = new DefaultCategoryDataset()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; modules.each{ m -&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; def dsCall = attributes.call(m)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; newDataset.addValue dsCall[0], 0, dsCall[1]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.dataset = newDataset&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Output&lt;br /&gt;&lt;/span&gt;Let&#39;s run and look at sample output... &lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.kartikshah.info/images/jmx-web-app-processing-time.jpg&quot; style=&quot;width: 553px; height: 333px;&quot; title=&quot;Web App Processing Time&quot; alt=&quot;web-app-processing-time&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.kartikshah.info/images/jmx-web-app-processing-time.jpg&quot;&gt;Click here for bigger images&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;Here is another script for Servlet Load Time &lt;br /&gt;&lt;br /&gt;This one uses some intermediate groovy knowledge with attributes param taking a closure. It allows user to perform transformation on the MBean parameters. Below in the script it performs operates on long objectName attribute to get servlet name parameter. &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;jmx {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; server &quot;service:jmx:rmi://localhost/jndi/rmi://localhost:1090/jmxconnector&quot; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; query &quot;jboss.web:*&quot; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; findAll &quot;j2eeType=Servlet&quot; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; chart{&lt;br /&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; chartType=&quot;Bar&quot;&lt;br /&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; attributes={m-&amp;gt; [m.loadTime, m.objectName.find(&quot;name=([^,]*)&quot;){it[1]}]}&lt;br /&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; labels=[&quot;Load Time per Servlet&quot;, &quot;Servlet&quot;, &quot;Time&quot;]&lt;br /&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; options=[false, true, true]&lt;br /&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; windowTitle=&quot;JBoss Servlet Processing Time&quot;&lt;br /&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; width=1200&lt;br /&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; height=700&lt;br /&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; orientation=&quot;HORIZONTAL&quot;&lt;br /&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; refreshRate=5000&lt;br /&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; show()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;and here is the output...&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.kartikshah.info/images/jmx-servlet-load-time.png&quot; style=&quot;width: 554px; height: 334px;&quot; title=&quot;Servlet Load Time&quot; alt=&quot;servlet-load-time&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.kartikshah.info/images/jmx-servlet-load-time.png&quot;&gt;Click here for bigger image&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Further you can, &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Add different type of chart support to the DSL - Bar, XY, trending, etc&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use/Extend to work with different application server and/or application&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Complete source code can be found at &lt;a href=&quot;http://github.com/kartikshah/jmx-dsl&quot;&gt;http://github.com/kartikshah/jmx-dsl&lt;/a&gt;&lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2010/02/groovy-dsl-jmx-reporting.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-2544990562223228398</guid><pubDate>Sat, 06 Feb 2010 03:35:00 +0000</pubDate><atom:updated>2010-12-05T16:48:38.948-06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">api</category><category domain="http://www.blogger.com/atom/ns#">collections</category><category domain="http://www.blogger.com/atom/ns#">google-collection</category><category domain="http://www.blogger.com/atom/ns#">java</category><title>Exploring Google Collections - Part 2</title><description>&lt;a href=&quot;http://blog.kartikshah.info/2010/01/exploring-google-collections-part-1.html&quot;&gt;In Part 1&lt;/a&gt;, we focused on few classes of google collection. Here in part 2, we will expand on the simple scenario and work on DOM like tree structure scenario. &lt;br /&gt;&lt;br /&gt;Consider a scenario of an external API provided by vendor. The API had tree like data structure, described by diagram below. &lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.kartikshah.info/images/node-component.gif&quot; style=&quot;margin: 0pt auto 10px; display: block; text-align: center; width: 742px; height: 267px;&quot; title=&quot;NodeComponent&quot; alt=&quot;Node Component Diagram&quot; /&gt;&lt;br /&gt;Now the problem was that the main data structure part of external API was POJO. Though it was a tree structure it did not provide any operations for traversal or find operations. Here is the watered down version of the component. &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;public class NodeComponent {&lt;br /&gt;    private String name;&lt;br /&gt;    private List&amp;lt;NodeComponent&amp;gt; children;&lt;br /&gt;    private Map&amp;lt;String, String&amp;gt; attributes;&lt;br /&gt;&lt;br /&gt;    public NodeComponent(String name)&lt;br /&gt;    {&lt;br /&gt;        this.name = name;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Getters and Setters omitted for brevity&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Let&#39;s see how google collection can be used to provide nice searcher methods. Consider following use cases: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Find child nodes based on node name&lt;/li&gt;&lt;li&gt;Find child nodes based on attribute name and value&lt;/li&gt;&lt;li&gt;Find child nodes on composite criteria of node name and attribute name and value&lt;/li&gt;&lt;/ul&gt;Lets implement cases using google collections.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Case 1: Find child nodes based on node name&lt;/span&gt;&lt;br /&gt;First we will define &lt;span style=&quot;font-style: italic;&quot;&gt;NodeNameCriteria&lt;/span&gt; implementing &lt;a href=&quot;http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicate.html&quot;&gt;Predicate&lt;/a&gt; interface&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;public class NodeNameCriteria implements Predicate&amp;lt;NodeComponent&amp;gt;&lt;br /&gt;{&lt;br /&gt;    private String nameCriteria;&lt;br /&gt;&lt;br /&gt;    public NodeNameCriteria(String nameCriteria)&lt;br /&gt;    {&lt;br /&gt;        this.nameCriteria = nameCriteria;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public boolean apply(NodeComponent node) &lt;br /&gt;    {&lt;br /&gt;        return node.getName().equals(nameCriteria);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Further, define &lt;span style=&quot;font-style: italic;&quot;&gt;NodeSearcher&lt;/span&gt; class which will represent current node and will provide all these helper methods &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;public class NodeSearcher&lt;br /&gt;{&lt;br /&gt;    private NodeComponent currentNode;&lt;br /&gt;&lt;br /&gt;    public NodeSearcher(NodeComponent currentNode)&lt;br /&gt;    {&lt;br /&gt;        this.currentNode = currentNode;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Collection&amp;lt;NodeComponent&amp;gt; findChildrenByNodeName(String name)&lt;br /&gt;    {&lt;br /&gt;        return Collections2.filter(currentNode.getChildren(),new NodeNameCriteria(name));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Case 2: Find child nodes based on attribute name and value&lt;/span&gt;&lt;br /&gt;Similar to first approach, this requires creating a Predicate implementation, let&#39;s name it &lt;span style=&quot;font-style: italic;&quot;&gt;AttributeNameValueCriteria&lt;/span&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;public class AttributeNameValueCriteria implements Predicate&amp;lt;NodeComponent&amp;gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private String nameCriteria;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private String valueCriteria;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public AttributeNameValueCriteria(String nameCriteria, String valueCriteria)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.nameCriteria = nameCriteria;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.valueCriteria = valueCriteria;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public boolean apply(NodeComponent component)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set&amp;lt;Map.Entry&amp;lt;String, String&amp;gt;&amp;gt; entrySet = component.getAttributes().entrySet();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set&amp;lt;Map.Entry&amp;lt;String, String&amp;gt;&amp;gt; matchedAttrSet = Sets.filter(entrySet, new Predicate&amp;lt;Map.Entry&amp;lt;String, String&amp;gt;&amp;gt;(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public boolean apply(Map.Entry&amp;lt;String, String&amp;gt; entry) {&lt;br /&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;&amp;nbsp; return nameCriteria.equals(entry.getKey()) &amp;amp;&amp;amp;&lt;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; valueCriteria.equals(entry.getValue());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return matchedAttrSet != null &amp;amp;&amp;amp; !matchedAttrSet.isEmpty();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Case 3: Find child nodes on composite criteria of node name and attribute name and value&lt;/span&gt;&lt;br /&gt;So far so good but the real benefit of defining the Predicate comes with the third case. In this case what is needed is to define a criteria which is composition of NodeNameCriteria and AttributeNameValueCriteria. We don&#39;t need to define third criteria implementation. Instead we will use Predicates compose method. Add following implmentation of findChildrenByNodeNameAndAttributeNameValue to NodeSearcher&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;public Collection&amp;lt;NodeComponent&amp;gt; findChildrenByNodeNameAndAttributeNameValue(String nodeName, String attrName, String attrValue)&lt;br /&gt;{&lt;br /&gt;     Predicate&amp;lt;NodeComponent&amp;gt; compositePredicate = Predicates.and(new NodeNameCriteria(nodeName),&lt;br /&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;&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;&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;&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; new AttributeNameValueCriteria(attrName, attrValue));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Collections2.filter(currentNode.getChildren(), compositePredicate);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;In simpler approach, one would have defined filter criteria as condition of if loop. But with implementing them as &lt;a href=&quot;http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicate.html&quot;&gt;Predicate&lt;/a&gt; implementation, you can reuse criteria implementation and mix and match with help of following &lt;a href=&quot;http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicates.html&quot;&gt;Predicates&lt;/a&gt; function and and or methods.&lt;br /&gt;&lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2010/02/exploring-google-collections-part-2_05.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-6047792969692819091</guid><pubDate>Mon, 01 Feb 2010 04:49:00 +0000</pubDate><atom:updated>2010-12-05T16:48:38.949-06:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">api</category><category domain="http://www.blogger.com/atom/ns#">collections</category><category domain="http://www.blogger.com/atom/ns#">google-collection</category><category domain="http://www.blogger.com/atom/ns#">java</category><title>Exploring google collections - Part 1</title><description>&lt;span style=&quot;font-weight: bold;&quot;&gt;Google Collection 1.0 released&lt;/span&gt;&lt;br /&gt;Google collections finally hit version 1.0. API provides rich data structures building on JDKs collection API. It also provides utility classes for working with collections. With this post I want to focus on few google collections classes and demonstrate how they help in working with collections. In part 1 of the post, we will deal with very simple example. Later in part 2 of the post, we will work with more involved real life example. &lt;br /&gt;&lt;br /&gt;We will focus on these classes: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicate.html&quot;&gt;Predicate&lt;/a&gt; and &lt;a href=&quot;http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicates.html&quot;&gt;Predicates&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html&quot;&gt;Function&lt;/a&gt; and &lt;a href=&quot;http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Functions.html&quot;&gt;Functions&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Collections2.html&quot;&gt;Collections2&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Scenarios&lt;/span&gt;&lt;br /&gt;While working with collections you may have noticed that code gets cluttered with for loops, nested for loops, or with for loops with embedded if loops. In most of these scenario what you are trying to do is to iterate through a given collection, either to search for specific elements or to operate on specific elements.&lt;br /&gt;&lt;br /&gt;Lets break down the typical cases:&lt;br /&gt;1. Iterating through a given collection and finding a specific element(s) based on criteria&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;for(Element element: elementsCollection){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(element.equals(something){ //Or any other test criteria based on state of element object&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //either add to collection of elements&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //or return this element&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;2. Iterating though a given collection and if certain criteria matches perform operation on the collection &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;for(Element element: elementCollection){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(element.equals(something){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //or operate on this element&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;As an outcome of this, code ends up with &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Code duplication of your iteration logic&lt;/li&gt;&lt;li&gt;Code duplication of your condition (matching criteria)&lt;/li&gt;&lt;li&gt;Code duplication of operation on the specific elements (This however can be avoided, if operation is re-factored into a method) &lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Google Collections Approach&lt;/span&gt;&lt;br /&gt;Lets start with very simple example, here is how google collection can help:&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;1. Define you matching criteria using &lt;a href=&quot;http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Predicate.html&quot;&gt;Predicate&lt;/a&gt; like &lt;/span&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Predicate&amp;lt;String&amp;gt; validEmailAddress = new Predicate&amp;lt;String&amp;gt;(){&lt;br /&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;&amp;nbsp; public boolean apply(String emailAddress){&lt;br /&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return emailAddress.contains(&quot;@&quot;);&lt;br /&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;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&lt;/pre&gt;This can be used as &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;List&amp;lt;String&amp;gt; emailList = Lists.newArrayList(&quot;abc@gmail.com&quot;, &quot;xyz@gmail.com&quot;, &quot;aaagmail.com&quot;);&lt;br /&gt;Collection&amp;lt;String&amp;gt; validEmailList = Collections2.filter(emailList, validEmailAddress);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;2. Define your operation on element using &lt;a href=&quot;http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Function.html&quot;&gt;Function&lt;/a&gt; like&lt;/span&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Function&amp;lt;String, String&amp;gt; extractUserName = new Function&amp;lt;String, String&amp;gt;(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public String apply(String emailAddress)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&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;&amp;nbsp; String userName = emailAddress.substring(0, emailAddress.indexOf(&#39;@&#39;));&lt;br /&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;&amp;nbsp; return userName;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&lt;/pre&gt;This can be used as &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;String&amp;gt; emailList = Lists.newArrayList(&quot;abc@gmail.com&quot;, &quot;xyz@gmail.com&quot;, &quot;aaa@gmail.com&quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;String&amp;gt; userNameList = Lists.transform(emailList,extractUserName);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We will take on more complex DOM-like tree based data structure in part 2 of the post...&lt;br /&gt;&lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2010/01/exploring-google-collections-part-1.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-4049982158266026561</guid><pubDate>Sat, 23 Jan 2010 16:19:00 +0000</pubDate><atom:updated>2014-08-09T16:46:00.070-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ast-transformation</category><category domain="http://www.blogger.com/atom/ns#">groovy</category><category domain="http://www.blogger.com/atom/ns#">java</category><title>Helpful tips - Working with AST Transformation</title><description>I have been playing with Groovy AST transformation for some time now. You can walk through some of the &lt;a href=&quot;http://blog.kartikshah.info/search/label/ast&quot;&gt;earlier posts here&lt;/a&gt;. With this entry I want to capture some of the lessons learnt, tips, etc.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Using AstViewer Tool (Inspect Ast)&lt;/span&gt;&lt;br /&gt;With Groovy 1.6 AST transformation, one of the difficulty was to come up with tree structure for the code you want to inject or change. It involves calling complex set of Statement and Expression APIs. It is ridden with intricate details of language grammar. With groovy 1.7 AstBuilder, you can use buildFromString and buildFromCode which is lot more easier. But still if you have to use buildFromSpec you will need to have some understanding of Statement/Expression API.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;One of the tool I have found useful is Groovy Console&#39;s AST Browser or Eclipse&#39;s ASTViewer. Write code you want to generate language structure for and try to replicate using API or using AstBuilder&#39;s buildFromSpec. The tool has gotten better from 1.6 to 1.7.&lt;br /&gt;Open Groovy Console and type in following code&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; def advice = new String(&quot;Hello AST&quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; println advice&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Go to &lt;span style=&quot;font-style: italic;&quot;&gt;Script&lt;/span&gt; --&amp;gt;&lt;span style=&quot;font-style: italic;&quot;&gt; Inspect Ast&lt;/span&gt; (or press Ctrl+T) and you will see the AST structure needed.&lt;br /&gt;&lt;img src=&quot;http://www.kartikshah.info/images/ast-viewer.png&quot; style=&quot;&quot; title=&quot;&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Educated Guess in Script&lt;/span&gt;&lt;br /&gt;With AstBuilder now you can just start building AST in main method or just as script. This has proven to be useful if you just want to compare what you are generating with what is displayed in AstBuilder.&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;def nodes = new AstBuilder().buildFromXXX{&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Working with Variables&lt;/span&gt;&lt;br /&gt;If you are using variables that gets replaced during runtime you may face problem generating AST. One of the method that I found useful was to replace the variable with static value and see if it works. If it does than the problem is possibly due to the type of the variable.&lt;br /&gt;For example, I wanted to generate&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; def advice = new &amp;lt;&amp;lt;variableClassName&amp;gt;&amp;gt;()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;where &lt;span style=&quot;font-style: italic;&quot;&gt;variableClassName&lt;/span&gt; will be passed in from annotation value. One option is to try generating it with static value like java.lang.String (or just String), if it works than there is some problem with the type of the variable you are passing.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Compile file individually (if using IDE)&lt;/span&gt;&lt;br /&gt;Sometimes the tools you are working with just does not seem to give different output even when you are changing things around in your code. Sometimes stale classes just gets called and you never see the output from the updated classes. You may want to compile both transformation class and the class where the transformation gets used.&amp;nbsp; &lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;ByteCode Viewer&lt;/span&gt;&lt;br /&gt;Also using &lt;a href=&quot;http://www.ej-technologies.com/products/jclasslib/overview.html&quot;&gt;Byte Code Viewer like this&lt;/a&gt; helps in looking at the classes that are getting generated. You can also write your class how it will look after AST transformation. Use byte code viewer to see the class and compare it with the class that is being generated through AST Transformation. See which statements are properly generated and which are not.&lt;br /&gt;&amp;nbsp;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Testcases&lt;/span&gt;&lt;br /&gt;Another extremely resourceful source for AstBuilder is test cases found &lt;a href=&quot;http://subversion.assembla.com/svn/AstBuilderPrototype/src/test/org/codehaus/groovy/ast/builder&quot;&gt;here&lt;/a&gt;. It contains rich example set of how to use each node in the builder specifically for buildFromSpec option. &lt;a href=&quot;http://subversion.assembla.com/svn/AstBuilderPrototype/src/test/org/codehaus/groovy/ast/builder/AstAssert.groovy&quot;&gt;AstAssert&lt;/a&gt; is another excellent utility to compare and test expected and actually generated structure. Looks like AstAssert class is not packaged with groovy-1.7, so you may need to download and drop it in your project.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Divide and Conquer&lt;/span&gt;&lt;br /&gt;Treat each section of code for which AST is being generated as separate section. Comment out blocks of code and gradually uncomment them to see which section is actually failing and/or not giving desired output.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Hope this helps! Drop in a line to share your tips or problems you face with Groovy&#39;s Ast transformation.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2010/01/helpful-tips-working-with-ast.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-3228288113843863647</guid><pubDate>Mon, 18 Jan 2010 06:37:00 +0000</pubDate><atom:updated>2014-08-09T16:46:00.067-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ast-transformation</category><category domain="http://www.blogger.com/atom/ns#">groovy</category><category domain="http://www.blogger.com/atom/ns#">groovy-1.7</category><category domain="http://www.blogger.com/atom/ns#">java</category><title>Revisiting Groovy AST Transformation with AstBuilder</title><description>Groovy AST is powerful tool to inject changes into classes at various compile phases. It allows one to operate on AST (Abstract Syntax Tree) to manipulate class structure.&lt;br /&gt;&lt;br /&gt;With Groovy 1.7 AstBuilder there are easier ways to write AST transformation. One can build AST nodes using one of following three options&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Build From String&lt;/li&gt;&lt;li&gt;Build From Spec&lt;/li&gt;&lt;li&gt;Build from Code&lt;/li&gt;&lt;/ul&gt;Previously on this blog, we experimented with &lt;a href=&quot;http://blog.kartikshah.info/2009/03/groovy-16-ast-transformation-example_5323.html&quot;&gt;Groovy 1.6 AST Transformation Example&lt;/a&gt; and also AOP style usage&amp;nbsp; at &lt;a href=&quot;http://blog.kartikshah.info/2009/07/groovy-ast-transformation-aop-style.html&quot;&gt;Groovy AST Transformation - AOP Style&lt;/a&gt;. Lets revisit this transformation from earlier post. &lt;br /&gt;&lt;br /&gt;Lets see how we can generate the AST tree using these new methods from &lt;a href=&quot;http://docs.codehaus.org/display/GroovyJSR/GEP+2+-+AST+Builder+Support&quot;&gt;AstBuilder&lt;/a&gt;. Recap&lt;a href=&quot;http://blog.kartikshah.info/2009/07/groovy-ast-transformation-aop-style.html&quot;&gt; this previous post before proceeding ahead&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Looks like we need to rewrite &lt;a href=&quot;http://blog.kartikshah.info/2009/07/groovy-ast-transformation-aop-style.html&quot;&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;initAdviceCall&lt;/span&gt;&lt;/a&gt; and &lt;a href=&quot;http://blog.kartikshah.info/2009/07/groovy-ast-transformation-aop-style.html&quot;&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;createMethodCall&lt;/span&gt;&lt;/a&gt; to experiment with new methods of AstBuilder.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Build From String&lt;/span&gt;&lt;br /&gt;Using buildFromString the task would become very easy. With this options, it is not required to build complicated statement and expression structure. All you need to do is embed code within string and pass it in to buildFromString method. If code you generate is not completely static in nature, you may have to parameterize the value. Here in this example, the declaration of &quot;advice&quot; instantiation depends on the Class value defined in the annotation.&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;&amp;nbsp; def initAdviceCall(classNodeType) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def codeString = &quot;def advice = new &quot; + classNodeType.type.typeClass.canonicalName + &quot;()&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def buildNodes = new AstBuilder().buildFromString(CompilePhase.SEMANTIC_ANALYSIS, true, codeString)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Statement stmt = buildNodes[0].statements[0]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stmt&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; def createMethodCall(method, Parameter[] parameters) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def codeString = &quot;advice.before (&quot; + &quot;&#39;$method.name&#39;&quot; +&quot;, [&quot; + parameters.collect {it.name}.join(&#39;,&#39;) + &quot;])&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def buildNodes = new AstBuilder().buildFromString(CompilePhase.SEMANTIC_ANALYSIS, true, codeString)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Statement stmt = buildNodes[0].statements[0]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stmt&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Build From Spec&lt;/span&gt;&lt;br /&gt;buildFromSpec option is more verbose. It also requires you to understand internal structure that is required to be build. With use of GroovyConsole&#39;s Inspect Ast option, it is not difficult to come up with the AST structure. &lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;&amp;nbsp; def initAdviceCall (classNodeType) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def buildNodes = new AstBuilder().buildFromSpec {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; expression {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; declaration {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; variable &quot;advice&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; token &quot;=&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; constructorCall(classNodeType.getType().getTypeClass()){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; argumentList()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Statement stmt = buildNodes[0]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stmt&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp; def createMethodCall(method, Parameter[] parameters) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def buildNodes = new AstBuilder().buildFromSpec {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; expression {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; methodCall {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; variable &quot;advice&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; constant &quot;before&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; argumentList {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; constant method.name&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; list {&lt;br /&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; parameters.each {variable it.name}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Statement stmt = buildNodes[0]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stmt&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There are some differences between using API directly and using spec builder option. One thing specifically that threw me off was that ConstructorCallExpression takes in ClassNode as parameter, however the constructorCall in builder takes Class. It wouldn&#39;t have been much of an annoyance, if I had read &lt;a href=&quot;http://docs.codehaus.org/display/GroovyJSR/GEP+2+-+AST+Builder+Support&quot;&gt;GEP-2&lt;/a&gt; which states that any expression taking ClassNode, for builder you just need to pass class instance. Well in this example, value provided by annotation was ClassNode, so I had to get Class and pass it on to constructorCall.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Build From Code&lt;/span&gt;&lt;br /&gt;Unlike above two options buildFromCode option did not work for me in above scenario. The problem I faced was I couldn&#39;t do def advice = &amp;lt;VariableClassName&amp;gt;() without using reflection. Method would have looked something like this&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;def initAdviceCall(classNodeType){&lt;br /&gt;new AstBuilder().buildFromCode {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; def advice = classNodeType.getType().getTypeClass().newInstance()&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Similarly, for createMethodCall, I would have to use reflection for passing in parameters. &lt;br /&gt;&lt;br /&gt;More later...&lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2010/01/revisiting-groovy-ast-transformation.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-7959704721995015964</guid><pubDate>Tue, 05 Jan 2010 13:48:00 +0000</pubDate><atom:updated>2014-08-09T16:46:00.086-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">groovy</category><category domain="http://www.blogger.com/atom/ns#">groovy-1.7</category><category domain="http://www.blogger.com/atom/ns#">java</category><title>Groovy Truth</title><description>Groovy had its truth. Groovy expanded on what Java allows to use in various control structures. While Java allows only boolean expression in if and while control structures, Groovy relaxed the requirement. In Groovy you can use objects in if and while expressions. Only a non-null and non-empty string will evaluate to true. A non-empty collection will evaluate to true. Non zero numbers will evaluate to true. &lt;br /&gt;&lt;br /&gt;With Groovy 1.7, Groovy Truth got better. You can now customize the Truth based on your requirement. This can be done by implementing boolean asBoolean() method. Implement the method on any object and logic defined in the method will be used to evaluate. Look at the following example&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;class Account {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String status&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean asBoolean(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(status != &#39;active&#39;) &lt;br /&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; false&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else &lt;br /&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; true&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;assert new Account(status:&#39;active&#39;)&lt;br /&gt;assert !new Account(status:&#39;prospect&#39;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can also expand (or change) existing classes like String, Integer, etc using metaClass. Let&#39;s &lt;span style=&quot;text-decoration: underline;&quot;&gt;expand&lt;/span&gt; the groovy truth to return null if the string value is &#39;null&#39;&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String.metaClass.asBoolean = {&lt;br /&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(delegate&amp;nbsp; == null || delegate == &#39;&#39; || delegate == &#39;null&#39;) false&lt;br /&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else true&lt;br /&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;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String nullString = null&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String nullLiteralString = &quot;null&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String validString = &quot;JohnDoe&quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String emptyString = &#39;&#39;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assert !nullString&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assert !nullLiteralString &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assert validString&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assert !emptyString&amp;nbsp; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Asserts are one place where the overridden logic will be applied. It works with if,while, and ternary operator as well. &lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;//continued from previous script&lt;br /&gt;println &quot;null&quot;?&quot;FALSE&quot;:&quot;TRUE&quot;&lt;br /&gt;&lt;br /&gt;str1 = &quot;null&quot;&lt;br /&gt;if(str1) println &quot;Valid String&quot; &lt;br /&gt;else println &#39;Null, empty or &quot;null&quot; literal string&#39;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you do not want to override the way an object evaluates to boolean globally. You can use categories.&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;class StringNullTruthCategory{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean asBoolean(String str){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(str || str == &#39;null&#39;)&amp;nbsp; false&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else true&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;use(StringNullTruthCategory){&lt;br /&gt;&amp;nbsp;&amp;nbsp; String parameterValue = &quot;null&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; if(parameterValue)&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; println &#39;Should not be printed&#39;&lt;br /&gt;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; println &#39;Should print&#39;&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def httpRequestParmValue = &quot;null&quot;&lt;br /&gt;print &#39;Valid Value: &#39;&lt;br /&gt;println httpRequestParmValue?&#39;YES&#39;:&#39;NO&#39;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Similarly, you can expand Integer&#39;s truth value if value is either zero or negative value. you can expand truth value of Map based on specific key-value. You have to be careful in doing so though, completely overriding the evaluation criteria can lead to confusion. You can apply on customize builder object. Let&#39;s say you have customized builder parsing order.xml into OrderEntity who has multiple OrderItems. OrderEntity truth can be derived from all of its OrderItem. &lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;class OrderEntity{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; OrderItem[] orderItems&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String status&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean asBoolean(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Define based on status or status of orderItems or presense/absence of orderItems&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if(currentOrder) { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //do time consuming process&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can define asBoolean objects in your Java class and use that definition to determine boolean value. However, you have to be careful of legacy Java Objects which has method asBoolean already defined for different purpose. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2010/01/groovy-truth_05.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-7554519035746502328</guid><pubDate>Thu, 31 Dec 2009 03:43:00 +0000</pubDate><atom:updated>2014-08-09T16:38:46.464-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">middleware</category><category domain="http://www.blogger.com/atom/ns#">mind-map</category><category domain="http://www.blogger.com/atom/ns#">mule</category><title>Mule Notes</title><description>Mule Mind Map&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.kartikshah.info/images/mule-1.jpeg&quot; style=&quot;margin: 0pt auto 10px; display: block; text-align: center; width: 918px; height: 570px;&quot; title=&quot;Mule Mind Map&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.kartikshah.info/images/mule-1.jpeg&quot;&gt;Click Here&lt;/a&gt; for full size image&lt;br /&gt;&lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2009/12/mule-notes.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-8082682942149575258</guid><pubDate>Fri, 20 Nov 2009 05:24:00 +0000</pubDate><atom:updated>2014-08-09T16:46:00.089-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">grails</category><category domain="http://www.blogger.com/atom/ns#">groovy</category><category domain="http://www.blogger.com/atom/ns#">java</category><title>Grails: belongsTo</title><description>&lt;span style=&quot;font-family: Verdana;&quot;&gt;&lt;br /&gt;In Grails &lt;span style=&quot;font-style: italic;&quot;&gt;hasMany&lt;/span&gt; and &lt;span style=&quot;font-style: italic;&quot;&gt;belongsTo&lt;/span&gt; are used to define relationship between objects. There are various other uses of &lt;span style=&quot;font-style: italic;&quot;&gt;belongsTo&lt;/span&gt;.&amp;nbsp; Trying to capture them here in this short post.&lt;br /&gt;&amp;nbsp;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;br /&gt;Let&#39;s take an example, say you have domain class &lt;span style=&quot;font-style: italic; font-weight: bold;&quot;&gt;TaskList&lt;/span&gt; which had many &lt;span style=&quot;font-style: italic; font-weight: bold;&quot;&gt;Task&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Direction of Access&lt;/span&gt;&lt;br /&gt;In class Task if you define belongsTo as&lt;br /&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; belongsTo = TaskList&lt;br /&gt;it means that Task object can not access its associated instance of TaskList&lt;br /&gt;If it is defined as&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; belongsTo = [taskList: TaskList]&lt;br /&gt;it means that Task object can access its associated instance of TaskList by doing task.taskList&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Cascading Deletes&lt;/span&gt;&lt;br /&gt;Only if belongsTo is defined cascading delete will happen. If TaskList is deleted all Tasks part of that TaskList will be deleted.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;addTo* method access&lt;/span&gt;&lt;br /&gt;For many-to-many relationship, defining belongsTo enables dynamic addTo* method&lt;br /&gt;Extending previous example, say each &lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;Task&lt;/span&gt; can have multiple &lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;Tag&lt;/span&gt; and a &lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;Tag&lt;/span&gt; can be given to multiple &lt;span style=&quot;font-weight: bold; font-style: italic;&quot;&gt;Task&lt;/span&gt;s. Defining belongsTo enables addTo* dynamic methods. e.g. task.addToTags(tag)&lt;br /&gt;&lt;/span&gt;&lt;br style=&quot;font-family: Verdana;&quot; /&gt;&lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2009/11/grails-belongsto.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-9033276149481013550</guid><pubDate>Fri, 10 Jul 2009 05:25:00 +0000</pubDate><atom:updated>2014-08-09T16:46:00.097-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">aop</category><category domain="http://www.blogger.com/atom/ns#">ast-transformation</category><category domain="http://www.blogger.com/atom/ns#">groovy</category><category domain="http://www.blogger.com/atom/ns#">java</category><title>Groovy AST Transformation - AOP Style</title><description>In my last &lt;a href=&quot;http://kartik-shah.blogspot.com/2009/03/groovy-16-ast-transformation-example_5323.html&quot;&gt;blog about AST Transformation&lt;/a&gt; I followed a sample example and created AssertParamsNotNull local transformation. Further, I wanted to create AST Transformation which is generic enough and performs any check before method is executed. In process, goal is to learn about AST Transformation. &lt;br /&gt;&lt;br /&gt;&lt;font size=&quot;3&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;BeforeAdvisor AST Transformation&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;Use case for BeforeAdvisor AST involves: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Authorization Checking - Security by checking role from context&lt;/li&gt;&lt;li&gt;Print Parameter values with which the method is called&lt;/li&gt;&lt;li&gt;Asserts Parameters are not null&lt;/li&gt;&lt;li&gt;Check various entry-conditions/Pre-Conditions of the method&lt;/li&gt;&lt;/ul&gt;To make transform generic enough, idea is to inject a method call to &lt;span style=&quot;font-style: italic;&quot;&gt;before method&lt;/span&gt; of advice for each method annotated with @BeforeAdvisor(MyPreConditionAdvice). Advice method can choose to implement any checks/conditions to be performed before actual methods gets executed. &lt;br /&gt;&lt;br /&gt;Few of the subtle characteristics of this type of solution are &lt;br /&gt;&lt;ul&gt;&lt;li&gt;It does not allow changing the method parameters.&amp;nbsp; &lt;br /&gt;&lt;/li&gt;&lt;li&gt;It does not allow to stop execution of method. However, you can throw runtime exception.&lt;/li&gt;&lt;li&gt;Advice needs no arg constructor and must implement method &lt;span style=&quot;font-style: italic;&quot;&gt;before &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Usage and Client&lt;/span&gt;&lt;br /&gt;Starting with class that will use this transform. Following defines script-level method with annotation having advice information.&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;package com.learn.sts.groovy.ast&lt;br /&gt;&lt;br /&gt;@com.learn.sts.groovy.ast.BeforeAdvisor(value= com.learn.sts.groovy.MyAdvice)&lt;br /&gt;def sayHello(name, name2)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; println &quot;Hello &quot; + name + name2&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;sayHello(&quot;World&quot;, &quot;Groovy&quot;) &lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Sample Advice&lt;/span&gt;&lt;br /&gt;The advice that we will try to invoke will be something like this. This advice just prints parameter value that method is being invoked with. But you can implement any of the use cases described above.&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;package com.learn.sts.groovy&lt;br /&gt;&lt;br /&gt;public class MyAdvice&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def before(String methodName, List listArg)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; println &#39;Entering Method &#39; + methodName + &#39; with params &#39; + listArg&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Annotation&lt;/span&gt;&lt;br /&gt;Now lets create the Annotation&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;package com.learn.sts.groovy.ast;&lt;br /&gt;&lt;br /&gt;import java.lang.annotation.Retention&lt;br /&gt;import java.lang.annotation.RetentionPolicy&lt;br /&gt;import java.lang.annotation.Target&lt;br /&gt;import java.lang.annotation.ElementType&lt;br /&gt;import org.codehaus.groovy.transform.GroovyASTTransformationClass&lt;br /&gt;@Retention(RetentionPolicy.SOURCE)&lt;br /&gt;@Target([ElementType.METHOD])&lt;br /&gt;@GroovyASTTransformationClass([&quot;com.learn.sts.groovy.ast.BeforeAdvisorASTTransformation&quot;])&lt;br /&gt;public @interface BeforeAdvisor {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Class value ();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;One difference to this annotation is that it declares a method value(). This allows us to get value being passed during annotation declaration on method.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;AST Transformation&lt;/span&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;groovy&quot;&gt;&lt;br /&gt;package com.learn.sts.groovy.ast&lt;br /&gt;&lt;br /&gt;//Imports section skipped for brevity&lt;br /&gt;&lt;br /&gt;@GroovyASTTransformation(phase=CompilePhase.SEMANTIC_ANALYSIS)&lt;br /&gt;public class BeforeAdvisorASTTransformation implements ASTTransformation &lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void visit(ASTNode[] nodes, SourceUnit source)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; AnnotationNode node = (AnnotationNode) nodes[0];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; final Expression classNode = node.getMember(&quot;value&quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;MethodNode&amp;gt; allMethods = source.AST?.classes*.methods.flatten()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; List annotatedMethods = allMethods.findAll{ MethodNode method -&amp;gt;&lt;br /&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; method.getAnnotations(new ClassNode(BeforeAdvisor))&lt;br /&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; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; annotatedMethods.each{MethodNode method -&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; List existingStatements = method.getCode().getStatements()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Parameter[] parameters = method.getParameters()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; int i = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; existingStatements.add(i++, initAdviceCall(classNode))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; existingStatements.add(i++, createMethodCall(method, parameters))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Statement initAdviceCall(classNode)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; return new ExpressionStatement(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; new DeclarationExpression(&lt;br /&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;&amp;nbsp; &amp;nbsp; new VariableExpression(&quot;advice&quot;),&lt;br /&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;&amp;nbsp; &amp;nbsp; new Token(Types.ASSIGNMENT_OPERATOR, &quot;=&quot;, -1, -1),&lt;br /&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;&amp;nbsp; &amp;nbsp; new ConstructorCallExpression(classNode.getType(), new ArgumentListExpression())&lt;br /&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;&amp;nbsp; &amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; public Statement createMethodCall(method, Parameter[] parameters){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; List parameterExpressionList = new ArrayList()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; parameters.each{ parameter -&amp;gt; parameterExpressionList.add(new VariableExpression(parameter))}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; return new ExpressionStatement(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; new MethodCallExpression(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; new VariableExpression(&quot;advice&quot;),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;before&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; new ArgumentListExpression(new ConstantExpression(method.getName()),&lt;br /&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;&amp;nbsp; new ListExpression(parameterExpressionList)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; )&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Couple of things to notice here: &lt;br /&gt;&lt;br /&gt;First, creation of the AST tree involves &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Creating instance of Advice Class - This is done through method &lt;span style=&quot;font-style: italic;&quot;&gt;initAdviceCall&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Invocation of the method before with methodName and Parameter List - This is done through method &lt;span style=&quot;font-style: italic;&quot;&gt;createMethodCall&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;Creating AST structure is not the easiest task. One approach that has worked for me is the write the sample code that you are trying to generate AST for and then use Groovy AST viewer in eclipse. &lt;br /&gt;&lt;br /&gt;Second, inspecting the value on ASTNode and getting Advice class value. First node contains information about the annotation and second node is the annotated node. &lt;br /&gt;&lt;br /&gt;&lt;font size=&quot;3&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Lessons Learned&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font size=&quot;2&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Compilation&lt;/span&gt;&lt;br /&gt;It was required to compile Transformations files first and then compile the classes that use AST Transformation. If I compiled all three of them together the AST Transformation did not kick in. I used Eclipse IDE and it forced me to use Compile Groovy File explicitly each time I made change. &quot;Build Automatically&quot; or &quot;Clean&quot; option did not work. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Script Level Methods vs all Class Methods&lt;/span&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;In &lt;a href=&quot;http://kartik-shah.blogspot.com/2009/03/groovy-16-ast-transformation-example_5323.html&quot;&gt;AssertParamsNotNull&lt;/a&gt; AST Transformation in previous blog, I used &lt;span style=&quot;font-style: italic;&quot;&gt;source.getAST()?.getMethods()&lt;/span&gt;&amp;nbsp; what it did is that it only found top level (Script Level) methods. So AST Transformation did not apply to Class Methods, it only got applied to Script Level Method. For this one I changed to source.ast?.classes*.methods.flatten() (Line 12 in &lt;span style=&quot;font-style: italic;&quot;&gt;BeforeAdvisorASTTransformation&lt;/span&gt;). This also become apparent once you see AST structure for a given class using Groovy AST View in eclipse. &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Retrive value from annotations&lt;/span&gt;&lt;br /&gt;ASTNode being passed to &lt;span style=&quot;font-style: italic;&quot;&gt;visit&lt;/span&gt; method carries information about the annotation. First element (node[0]) contains information about annotation. You can get the values passed in to annotation during the visit method and use it during the transformation. In case above we get class passed in as value and it gets instantiated and before method gets invoked.&lt;br /&gt;&lt;br /&gt;&lt;font size=&quot;2&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Groovy Compilation&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;When groovy compiler is invoked, any sourcefile.groovy goes under series of transformations. &lt;br /&gt;From Source --&amp;gt; ANTLR Tokens --&amp;gt; ANTLR AST --&amp;gt; Groovy AST --&amp;gt; Bytecode&lt;br /&gt;&lt;br /&gt;Using AST Transformation, we manipulate the way groovy AST gets generated. It allows to insert additonal statements. &lt;br /&gt;&lt;br /&gt;There are various CompilerPhase that goes along with this process. I couldn&#39;t find much documentation on the process. Best information is found on &lt;a href=&quot;http://blackdragsview.blogspot.com/2006/11/chitchat-with-groovy-compiler.html&quot;&gt;Jochen Theodorou&#39;s blog post&lt;/a&gt;&lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2009/07/groovy-ast-transformation-aop-style.html</link><author>noreply@blogger.com (Kartik Shah)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-19518284.post-6920448346239865337</guid><pubDate>Sun, 21 Jun 2009 04:35:00 +0000</pubDate><atom:updated>2014-08-09T16:46:00.082-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">administration</category><category domain="http://www.blogger.com/atom/ns#">groovy</category><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">jfreechart</category><category domain="http://www.blogger.com/atom/ns#">jmx</category><category domain="http://www.blogger.com/atom/ns#">swingbuilder</category><category domain="http://www.blogger.com/atom/ns#">weblogic</category><title>JMX, Groovy, JFreeChart and Swing</title><description>&lt;span style=&quot;font-weight: bold; font-family: Verdana;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;Recently, I worked on creating JMX based dashboard application showing Weblogic instances&#39; information. During the exercise I came across &lt;/span&gt;&lt;a style=&quot;font-family: Verdana;&quot; href=&quot;http://groovy.codehaus.org/Groovy+and+JMX&quot;&gt;JMX and Groovy examples &lt;/a&gt;&lt;br style=&quot;font-family: Verdana;&quot; /&gt;&lt;br style=&quot;font-family: Verdana;&quot; /&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;Using JMX, Groovy, Swing and JFreeChart, I came up with a dashboard application which looks like this. &lt;/span&gt;&lt;br style=&quot;font-family: Verdana;&quot; /&gt;&lt;br style=&quot;font-family: Verdana;&quot; /&gt;&lt;a style=&quot;font-family: Verdana;&quot; href=&quot;http://www.flickr.com/photos/shahkartikr/3645249363/&quot; title=&quot;Memory-Usage by shahkartikr, on Flickr&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2431/3645249363_1fb8dacf03.jpg&quot; alt=&quot;Memory-Usage&quot; height=&quot;202&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;&lt;br style=&quot;font-family: Verdana;&quot; /&gt;&lt;br style=&quot;font-family: Verdana;&quot; /&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;It show memory usage on two instances. It automatically updates every 10 seconds and redraws chart. &lt;/span&gt;&lt;br style=&quot;font-family: Verdana;&quot; /&gt;&lt;br style=&quot;font-family: Verdana;&quot; /&gt;&lt;span style=&quot;font-family: Verdana;&quot;&gt;Surprisingly (or not so surprisingly), code required to be written to perform this activity is minimal. Specifically thanks to Groovy&#39;s SwingBuilder and JMX libraries.&lt;/span&gt; Groovy makes the task of using 4 different technologies really easy and fun.&lt;br /&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;&lt;br /&gt;import org.jfree.chart.ChartFactory&lt;br /&gt;import javax.swing.WindowConstants as WC&lt;br /&gt;import javax.management.remote.*&lt;br /&gt;import javax.naming.Context;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * WeblogicJMXReporter monitors Memory value for given node&lt;br /&gt; * @author kartik.shah&lt;br /&gt; */&lt;br /&gt;public class WeblogicJMXReporter&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    static void main(String[] args)&lt;br /&gt;    {&lt;br /&gt;    	def env = [:]&lt;br /&gt;    	env[&quot;java.naming.factory.initial&quot;] = &quot;weblogic.jndi.WLInitialContextFactory&quot;&lt;br /&gt;    	env[Context.SECURITY_PRINCIPAL] = &quot;system&quot;&lt;br /&gt;    	env[Context.SECURITY_CREDENTIALS] = &quot;*******&quot; //Password is always stars&lt;br /&gt;    	env[JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES] = &quot;weblogic.management.remote&quot;&lt;br /&gt;    	def jmxServiceURL = new JMXServiceURL(&quot;http&quot;, &quot;10.50.120.110&quot;, 19400,&quot;/jndi/weblogic.management.mbeanservers.domainruntime&quot;)&lt;br /&gt;    	def server = JMXConnectorFactory.connect(jmxServiceURL, env).MBeanServerConnection&lt;br /&gt;&lt;br /&gt;    	def chart1Map = getChart(&quot;node1_svr&quot;, server);&lt;br /&gt;    	def piedata1 = chart1Map.&quot;pieData&quot;&lt;br /&gt;    	def chart1 = chart1Map.&quot;Chart&quot;&lt;br /&gt;    	def jvmInfo1 = chart1Map.&quot;MBean&quot;&lt;br /&gt;    	&lt;br /&gt;    	def chart2Map = getChart(&quot;node2_svr&quot;, server);&lt;br /&gt;    	def piedata2 = chart2Map.&quot;pieData&quot;&lt;br /&gt;    	def chart2 = chart2Map.&quot;Chart&quot;&lt;br /&gt;    	def jvmInfo2 = chart2Map.&quot;MBean&quot;&lt;br /&gt;    	&lt;br /&gt;    	def swing = new groovy.swing.SwingBuilder()&lt;br /&gt;&lt;br /&gt;    	def frame = swing.frame(title:&#39;Weblogic INT Memory Usage&#39;, defaultCloseOperation:WC.EXIT_ON_CLOSE, &lt;br /&gt;    	                        size:[800,600], locationRelativeTo: null) {&lt;br /&gt;    	    borderLayout()&lt;br /&gt;    	    panel(id:&#39;canvas&#39;) { rigidArea(width:700, height:250) }&lt;br /&gt;    	}&lt;br /&gt;&lt;br /&gt;    	def bounds1 = new java.awt.Rectangle(0,0, 350,250).bounds&lt;br /&gt;    	def bounds2 = new java.awt.Rectangle(351,0, 350, 250).bounds&lt;br /&gt;    	while(true)&lt;br /&gt;    	{&lt;br /&gt;    	    recalculatePieData(piedata1, jvmInfo1)&lt;br /&gt;    	    recalculatePieData(piedata2, jvmInfo2)&lt;br /&gt;        &lt;br /&gt;        	chart1.fireChartChanged()&lt;br /&gt;        	chart2.fireChartChanged()&lt;br /&gt;        	&lt;br /&gt;        	frame.pack()&lt;br /&gt;        	frame.show()&lt;br /&gt;        	chart1.draw(swing.canvas.graphics, bounds1)&lt;br /&gt;        	chart2.draw(swing.canvas.graphics, bounds2)&lt;br /&gt;        	sleep(10000)&lt;br /&gt;    	}&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    static getChart(nodeName, server)&lt;br /&gt;    {&lt;br /&gt;    	def jvmInfo = new GroovyMBean(server, &#39;com.bea:Location=&#39;+nodeName+&#39;,Name=&#39;+nodeName+&#39;,ServerRuntime=&#39;+nodeName+&#39;,Type=JVMRuntime&#39;)&lt;br /&gt;    	def piedata = new org.jfree.data.general.DefaultPieDataset()&lt;br /&gt;    	piedata.setValue &quot;Free&quot;, jvmInfo.HeapFreeCurrent&lt;br /&gt;    	piedata.setValue &quot;Used&quot;, jvmInfo.HeapSizeMax - jvmInfo.HeapFreeCurrent&lt;br /&gt;    	def options = [true, true, true]&lt;br /&gt;    	def chart = ChartFactory.createPieChart(nodeName, piedata, *options)&lt;br /&gt;    	chart.backgroundPaint = java.awt.Color.white&lt;br /&gt;        &lt;br /&gt;        [&quot;MBean&quot;:jvmInfo, &quot;pieData&quot;:piedata, &quot;Chart&quot;:chart]&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    static recalculatePieData(piedata, jvmInfo)&lt;br /&gt;    {&lt;br /&gt;    	piedata.setValue &quot;Free&quot;, jvmInfo.HeapFreeCurrent&lt;br /&gt;    	piedata.setValue &quot;Used&quot;, jvmInfo.HeapSizeMax - jvmInfo.HeapFreeCurrent&lt;br /&gt;    	println piedata.getValue(&quot;Free&quot;)&lt;br /&gt;    	println piedata.getValue(&quot;Used&quot;)&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;For purpose of this blog and keeping it simple, I kept it all in one groovy class. &lt;br /&gt;  &lt;div class=&quot;flockcredit&quot; style=&quot;text-align: right; color: #CCC; font-size: x-small;&quot;&gt;Blogged with the &lt;a href=&quot;http://www.flock.com/blogged-with-flock&quot; style=&quot;color: #999; font-weight: bold;&quot; target=&quot;_new&quot; title=&quot;Flock Browser&quot;&gt;Flock Browser&lt;/a&gt;&lt;/div&gt;</description><link>http://blog.kartikshah.com/2009/06/jmx-groovy-jfreechart-and-swing.html</link><author>noreply@blogger.com (Kartik Shah)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm3.static.flickr.com/2431/3645249363_1fb8dacf03_t.jpg" height="72" width="72"/><thr:total>2</thr:total></item></channel></rss>