Archive for 8월, 2012

link- Groovy Almanac

2012/08/27

http://groovy-almanac.org/

from mobile

Advertisements

link – 스테이지홀릭 종이아띠전시

2012/08/25

http://www.stageholic.com/ 종이아띠 꼬깃꼬깃

from mobile

link : vert.x – asynchronous web app framework

2012/08/24

Vert.x- Effortless asynchronous application development for the modern web and enterprise
http://vertx.io/

한국에 있다는 세가지 개발 방법론

2012/08/24

from twitter

@mimul 우리 나라에는 세가지 개발 방법론이 있는 듯. “Meeting Driven Development(회의[입] 주도 개발)”, “Overtime-Driven..(야근 주도 개발)”, “Deadline-Driven..(납기일 주도 개발)”.

from mobile

[groovy] using XmlSlurper remove, add, append to xml node

2012/08/24

groovy XmlSlurper is very useful!!!

sample.xml

<service>
  <method name="remove">
  </method>
  <method name="add">
    <param name="param1"/>
  </method>
</service>

sample.groovy

def root = new XmlSlurper().parse(new File("sample.xml"));
root.method.each{ mtd ->
  def mtdname = mtd.name.toString()
  // remove node 
  if(mtdname.equals("remove")){ mtd.replaceNode{} }
  // add node
  if(mtdname.equals("add")){ mtd.param + { exception(name:"Exception") } }
  // append node
  mtdname.appendNode{ mtd.method(name: "appendmethod") }
}

result

<service>
  <method name="add">
    <param name="param1"/>
    <exception name="Exception"/>
  </method>
  <method name="appendmethod"/>
</service>

[tip] wordpress.com tip

2012/08/24

– autosave : every 2 min.

– posting source code : http://en.support.wordpress.com/code/posting-source-code/ tistory는 소스 넣는게 예쁘지가 않더라..
cf) javascript는 안딤..

– post by email : http://en.support.wordpress.com/post-by-email/ 고유 email을 생성하여 발송하면 등록되는 유용한 기능..
첨부 가능하고, shortcodes 라는 유용한 기능도 있다.
ex) [category x,y] [status draft] [title mytitle] [tags it, tip]

– publicize : http://en.support.wordpress.com/publicize/ facebook, tumblr, twitter 발행기능. tistory로도 보내보고 싶지만..

spring Restful api documentation

2012/08/24

[purpose]
– make RESTful API Documentation
– Using Spring framework
– autogenerate

[Review solutions]
SPRINGDOCLET : javadoc style로 rest api user document 로는 부족함

RESTDOCLET : 목적에 부합
maven plugin, web application type
param description not support, rest error code not support
controller에 정의한 mapping 미인식

WSDOC : simple 충분하지않음 rest error, param description nor support

SWAGGER : spring 지원 불충분, 복잡…

[try – restdoclet]
– fail maven setting
– use library
– process : java source ->; xml using xmldoc ->; xml using jibx ->; html using template
– preperation
spring restful application source & libraries
library :
rsetdoclet lib : restdoclet-doclet-2.2.0.jar, restdoclet-plugin-2.2.0.jar, jibx-run-1.2.1.jar, from https://oss.sonatype.org/index.html#nexus-search;classname~RESTdoclet
spring lib : spring-web-3.0.5.RELEASE.jar, spring-context-3.0.5.RELEASE.jar, commons-lang-2.6.jar,
javadoc lib : tools.jar,
ant lib : ant-launcher.jar, ant.jar
etc : commons-collections-3.2.jar, log4j-1.2.15.jar,

thanks iggroup restdoclet! https://github.com/IG-Group/RESTdoclet

demo.groovy

import groovy.text.SimpleTemplateEngine
import org.apache.commons.collections.CollectionUtils
import org.jibx.runtime.JiBXException
import com.iggroup.oss.restdoclet.doclet.XmlDoclet
import com.iggroup.oss.restdoclet.doclet.type.*
import com.iggroup.oss.restdoclet.doclet.util.*
import com.iggroup.oss.restdoclet.plugin.io.*
import com.iggroup.oss.restdoclet.plugin.util.ServiceUtils
import com.sun.tools.javac.util.*
import com.sun.tools.javac.util.Options
import com.sun.tools.javadoc.*
class demo {
	static def SERVICES_TEMPLATE = &amp;amp;quot;src/main/resources/services.jsp&amp;amp;quot;;
	static def SERVICE_TEMPLATE = &amp;amp;quot;src/main/resources/service.jsp&amp;amp;quot;;
	def reportDir, restsrcDir , packageNames = [] , appname = &amp;amp;quot;&amp;amp;quot; , version
	static main(args) {
		def me = new demo();
		me.restsrcDir = &amp;amp;quot;my-rest-web/src/main/java&amp;amp;quot;
		me.reportDir = &amp;amp;quot;my-rest-web/doc/restdoc&amp;amp;quot;
		me.packageNames = {&amp;amp;quot;com.my.rest&amp;amp;quot;}
		me.appname =  [&amp;amp;quot;APPLICATION&amp;amp;quot;:&amp;amp;quot;my-rest&amp;amp;quot; ]
		me.version = [&amp;amp;quot;version&amp;amp;quot;:1.0, timestamp:new Date()]
		
		me.makexmldoc()
		me.build();
	}
	def ant = new AntBuilder()
	def controllers = []// ArrayList&amp;lt;;Controller&amp;gt;; 
	def outputDirectory = &amp;amp;quot;my-rest&amp;amp;quot;;

	// gathering Controller.java files ( except Sample)
	def getRestControllers(){
		def list = []
		new File(restsrcDir).eachFileRecurse {
			if(it.name.endsWith(&amp;amp;quot;Controller.java&amp;amp;quot;)){ list.add(it) }
		}
		return list;
	}
	
	def makexmldoc(){
	    ant.mkdir(dir:reportDir);
		Context context = new Context();
		Options compOpts = Options.instance(context);
		compOpts.put(&amp;amp;quot;-sourcepath&amp;amp;quot;, new File(restsrcDir).absolutePath);
		compOpts.put(&amp;amp;quot;-classpath&amp;amp;quot;, getClassLibs());
		
		def javaNames = new ListBuffer&amp;lt;;String&amp;gt;;();
		getRestControllers().each{ javaNames.append(it.getPath()); }
		def subPackages = new ListBuffer&amp;lt;;String&amp;gt;;();
		for (String packageName : packageNames) {
			subPackages.append(packageName);
		}
		new Messager(context,&amp;amp;quot;application&amp;amp;quot;)
		JavadocTool javadocTool = JavadocTool.make0(context);
		def rootDoc = javadocTool.getRootDocImpl( &amp;amp;quot;&amp;amp;quot;, &amp;amp;quot;utf-8&amp;amp;quot;,
                    new ModifierFilter(ModifierFilter.ALL_ACCESS),
                    javaNames.toList(), new ListBuffer&amp;lt;;String[]&amp;gt;;().toList(),
                    false, subPackages.toList(), new ListBuffer&amp;lt;;String&amp;gt;;().toList(),
                    false, false, true);
		
		new XmlDoclet().start(rootDoc);
		def myDir = &amp;amp;quot;target/restdoc&amp;amp;quot;
		ant.mkdir(dir:myDir)
		new ControllerUriAppender().add(rootDoc, myDir);
	}
	def build()   {
		def myDir = &amp;amp;quot;target/restdoc&amp;amp;quot;
	    javadocs(myDir);
	    services(myDir);
	}

	def javadocs(rootDir){
		new File(rootDir).eachFileRecurse {
			if(it.name.endsWith(Controller.FILE_SUFFIX)){
				final Controller cntrl = JiBXUtils.unmarshallController(it);
				if (!controllers.contains(cntrl)) { controllers.add(cntrl); }
			}
		}
	}
	
	def services(baseDirectory)  {
	   def services = new ArrayList&amp;lt;;Service&amp;gt;;();
	   def uriMethodMappings = [:]
	   def uriControllerMappings = new HashMap&amp;lt;;String, Controller&amp;gt;;();
	   def multiUriMappings = new HashMap&amp;lt;;String, Collection&amp;lt;;Uri&amp;gt;;&amp;gt;;();
	   for (Controller controller : controllers) {
		  for (Method method : controller.getMethods()) {
			 def uris = method.getUris();
			 if (!uris.isEmpty()) {
				String multiUri = uris.join(&amp;amp;quot;, &amp;amp;quot;)
				multiUriMappings.put(multiUri, uris);
				def methodList = uriMethodMappings.get(multiUri);
				if (methodList == null) {
				   methodList = new ArrayList&amp;lt;;Method&amp;gt;;();
				   uriMethodMappings.put(multiUri, methodList);
				}
				methodList.add(method);
				uriControllerMappings.put(multiUri, controller);
			 }
		  }
	   }
 
	   int identifier = 1;
	   for (String uri : uriControllerMappings.keySet()) {
		  Controller controller = uriControllerMappings.get(uri);
		  ArrayList&amp;lt;;Method&amp;gt;; matches = uriMethodMappings.get(uri);
		  Service service = new Service(identifier, multiUriMappings.get(uri), new Controller(
				controller.getType(), controller.getJavadoc(), matches));
		  services.add(service);
		  generateServiceHtml( appname, version, service)
		  identifier++;
	   }
 
	   Services list = new Services();
	   for (Service service : services) {
		  org.apache.commons.collections.Predicate predicate = new ControllerTypePredicate(service.getController().getType());
		  if (CollectionUtils.exists(list.getControllers(), predicate)) {
			 ControllerSummary controller = (ControllerSummary) CollectionUtils.find(list.getControllers(), predicate);
			 controller.addService(service);
		  } else {
			 ControllerSummary controller = new ControllerSummary(service.getController().getType(), service.getController().getJavadoc());
			 controller.addService(service);
			 list.addController(controller);
		  }
	   }
		def toFile = reportDir+&amp;amp;quot;/services.html&amp;amp;quot;
		generateHtml(toFile, [&amp;amp;quot;param&amp;amp;quot; : appname,  &amp;amp;quot;props&amp;amp;quot;:version, &amp;amp;quot;services&amp;amp;quot;:list.getServices()], SERVICES_TEMPLATE);
	}
	
	def generateServiceHtml(  param, props, svc){
		def toFile = reportDir+&amp;amp;quot;/service-&amp;amp;quot; + svc.identifier  + &amp;amp;quot;.html&amp;amp;quot;
		generateHtml(toFile, [&amp;amp;quot;param&amp;amp;quot; : param,  &amp;amp;quot;props&amp;amp;quot;:props, &amp;amp;quot;service&amp;amp;quot;:svc], SERVICE_TEMPLATE);
	}
	
	def generateHtml(def toFile, def binding, def templateFile, encoding = &amp;amp;quot;UTF-8&amp;amp;quot;){
		def reader = new File(templateFile).newReader();
		def template = new SimpleTemplateEngine().createTemplate(reader).make(binding);
		new File(toFile).write(template.toString(), encoding)
	}

	// for javadoc compile
	def getClassLibs(){
		return [ &amp;amp;quot;../my-rest/WEB-INF/lib/commons-logging.jar&amp;amp;quot;, &amp;amp;quot;../my-rest/WEB-INF/lib/spring-XXXX-X.X.X.RELEASE.jar&amp;amp;quot;
			// ...  other libraries
			].join(&amp;amp;quot;;&amp;amp;quot;)
	}
}

ControllerUriAppender.groovy ( for controller’s uri appending)

import static com.iggroup.oss.restdoclet.doclet.util.AnnotationUtils.*
import static com.iggroup.oss.restdoclet.doclet.util.JiBXUtils.marshallController
import groovy.util.slurpersupport.GPathResult
import groovy.xml.*
import org.springframework.web.bind.annotation.RequestMapping
import com.iggroup.oss.restdoclet.doclet.type.Controller
import com.sun.javadoc.*
class ControllerUriAppender {
	def add(RootDoc rootDoc, outputpath){
		for (ClassDoc classDoc : rootDoc.classes()) {
			if (isAnnotated(classDoc, org.springframework.stereotype.Controller.class)) {
			   AnnotationValue value = elementValue(	classDoc, RequestMapping.class, &amp;amp;quot;value&amp;amp;quot;)
			   def rooturi  = value.toString().replaceAll(&amp;amp;quot;&amp;amp;quot;&amp;amp;quot;,&amp;amp;quot;&amp;amp;quot;);
			   def xmlname = classDoc.qualifiedName().replace('.' as char, File.separatorChar) + Controller.FILE_SUFFIX
			   def root = new XmlSlurper().parse(new File(xmlname));
			   if(value!=null){
				   root.method.each{ mtd -&amp;gt;;
					   def mtdname = mtd.name.toString()
					   if(mtdname.endsWith(&amp;amp;quot;Null&amp;amp;quot;)||mtdname.endsWith(&amp;amp;quot;Error&amp;amp;quot;)){ // remove null filter mapping
						   mtd.replaceNode{}
					   }else{
						   if(mtd.uri==&amp;amp;quot;&amp;amp;quot;){
							   mtd.javadoc + { 
								   uri {
									   uri(rooturi)
									   deprecated(false)
									   type(&amp;amp;quot;java.lang.String&amp;amp;quot;)
								   }
							   }
						   }else{
						   		mtd.uri.uri = rooturi + mtd.uri.uri
						   }
						   
						   def mtddoc = classDoc.methods().find { //// add parameter comment
							   it.name().equals(mtdname) 
						   }
						   
						   mtd.&amp;amp;quot;request-param&amp;amp;quot;.each{ rqparam -&amp;gt;;
							   if(rqparam.javadoc==&amp;amp;quot;&amp;amp;quot;){
								   def paramdoc = mtddoc.paramTags().find{ paramtag -&amp;gt;;
									   paramtag.parameterName().equals(rqparam.name)
								   }
								   rqparam.type + {
									   javadoc(paramdoc?.parameterComment() )
								   }
							   }
						   }

						   // response-param exception javadoc 추가.
						   mtd.&amp;amp;quot;response-param&amp;amp;quot;.each{ rpparam -&amp;gt;;
							   if(rpparam.name.equals(&amp;amp;quot;Exception&amp;amp;quot;)){
								   def exceptiondoc = mtddoc.throwsTags().find{ paramtag -&amp;gt;;
									   paramtag.exceptionName() .equals(rpparam.name.toString())
								   }
								   if(rpparam.javadoc==&amp;amp;quot;&amp;amp;quot;){
									   rpparam.type + {
										   javadoc(exceptiondoc?.exceptionComment() )
									   }
								   }
							   }
						   }
					   }
				   }
			   }
			   def outputBuilder = new StreamingMarkupBuilder()
			   outputBuilder.encoding =&amp;amp;quot;UTF-8&amp;amp;quot;
			   def result = outputBuilder.bind{ 
				   mkp.xmlDeclaration()
				   mkp.yield root 
			   }
			   def ant = new AntBuilder()
			   def myDir = outputpath + &amp;amp;quot;/&amp;amp;quot;+xmlname
			   ant.touch(file:myDir, mkdirs:true, verbose:false)
			   def fwriter = new FileWriter(myDir  );// .write(result);
			   XmlUtil.serialize(result, fwriter)
			   fwriter.close();
			}
		 }
	}
}

template : services.jsp

&amp;lt;;div class=&amp;amp;quot;projectDetails&amp;amp;quot;&amp;gt;;

   &amp;lt;;h1 class=&amp;amp;quot;mainHeading&amp;amp;quot;&amp;gt;;
      &amp;lt;;span class=&amp;amp;quot;title&amp;amp;quot;&amp;gt;;RESTdoclet for:&amp;lt;;/span&amp;gt;;
      &amp;lt;;span class=&amp;amp;quot;application&amp;amp;quot;&amp;gt;;
         &amp;lt;;em&amp;gt;;&amp;lt;;span class=&amp;amp;quot;application&amp;amp;quot;&amp;gt;;${param[&amp;amp;quot;APPLICATION&amp;amp;quot;]}&amp;lt;;/span&amp;gt;;&amp;lt;;/em&amp;gt;;
      &amp;lt;;/span&amp;gt;;
   &amp;lt;;/h1&amp;gt;;

   &amp;lt;;h3&amp;gt;;
      &amp;lt;;span class=&amp;amp;quot;version&amp;amp;quot;&amp;gt;;Version: &amp;lt;;em&amp;gt;;${props.version}&amp;lt;;/em&amp;gt;;&amp;lt;;/span&amp;gt;;
      &amp;lt;;span class=&amp;amp;quot;timestamp&amp;amp;quot;&amp;gt;;Creation: &amp;lt;;em&amp;gt;;${props.timestamp}&amp;lt;;/em&amp;gt;;&amp;lt;;/span&amp;gt;;
   &amp;lt;;/h3&amp;gt;;
&amp;lt;;/div&amp;gt;;

&amp;lt;;div class=&amp;amp;quot;services&amp;amp;quot;&amp;gt;;
&amp;lt;;!-- 
   &amp;lt;;div class=&amp;amp;quot;sourceControlLocation&amp;amp;quot;&amp;gt;;
      Under version control at &amp;lt;;a href=&amp;amp;quot;${props.scmUrl}&amp;amp;quot;&amp;gt;;${props.scmUrl}&amp;lt;;/a&amp;gt;;
   &amp;lt;;/div&amp;gt;;
 --&amp;gt;;
   &amp;lt;;table class=&amp;amp;quot;topLevel&amp;amp;quot;&amp;gt;;
      &amp;lt;;thead&amp;gt;;
      &amp;lt;;tr&amp;gt;;
         &amp;lt;;th&amp;gt;;URI&amp;lt;;/th&amp;gt;;
         &amp;lt;;th&amp;gt;;Actions&amp;lt;;/th&amp;gt;;
      &amp;lt;;/tr&amp;gt;;
      &amp;lt;;/thead&amp;gt;;
      &amp;lt;;tbody&amp;gt;;&amp;lt;;% services.each{ service -&amp;gt;; %&amp;gt;;
            &amp;lt;;tr&amp;gt;;
               &amp;lt;;td class=&amp;amp;quot;uri&amp;amp;quot;&amp;gt;;&amp;lt;;%  service.uris.each{ urix -&amp;gt;; %&amp;gt;;
                     &amp;lt;;div class=&amp;amp;quot;active&amp;amp;quot;&amp;gt;;
                        &amp;lt;;a href=&amp;amp;quot;service-${service.identifier}.html&amp;amp;quot;&amp;gt;;${urix.uri}&amp;lt;;/a&amp;gt;;
                     &amp;lt;;/div&amp;gt;;&amp;lt;;% } %&amp;gt;;&amp;lt;;/td&amp;gt;;
               &amp;lt;;td&amp;gt;;
                  &amp;lt;;table class=&amp;amp;quot;methods&amp;amp;quot;&amp;gt;;
                     &amp;lt;;% service.methods.each{ method-&amp;gt;; %&amp;gt;;
                        &amp;lt;;tr&amp;gt;;
                           &amp;lt;;td class=&amp;amp;quot;requestMethod&amp;amp;quot;&amp;gt;;${method.requestMethod}&amp;lt;;/td class=&amp;amp;quot;javadoc&amp;amp;quot;&amp;gt;;
                           &amp;lt;;td class=&amp;amp;quot;javadoc&amp;amp;quot;&amp;gt;;${method.javadoc}&amp;lt;;/td&amp;gt;;
                        &amp;lt;;/tr&amp;gt;;&amp;lt;;% } %&amp;gt;;
                  &amp;lt;;/table&amp;gt;;
               &amp;lt;;/td&amp;gt;;
            &amp;lt;;/tr&amp;gt;;
      &amp;lt;;% }  %&amp;gt;;
      &amp;lt;;/tbody&amp;gt;;
   &amp;lt;;/table&amp;gt;;
&amp;lt;;/div&amp;gt;;

template service.jsp

&amp;lt;;div class=&amp;amp;quot;projectDetails&amp;amp;quot;&amp;gt;;
   &amp;lt;;h1 class=&amp;amp;quot;mainHeading&amp;amp;quot;&amp;gt;;
      &amp;lt;;span class=&amp;amp;quot;title&amp;amp;quot;&amp;gt;;RESTdoclet for:&amp;lt;;/span&amp;gt;;
      &amp;lt;;em&amp;gt;;&amp;lt;;a href=&amp;amp;quot;services.html&amp;amp;quot;&amp;gt;;${param[&amp;amp;quot;APPLICATION&amp;amp;quot;]}&amp;lt;;/a&amp;gt;;&amp;lt;;/em&amp;gt;;
      &amp;lt;;% service.uris.each{ urix -&amp;gt;; %&amp;gt;;
         &amp;lt;;span class=&amp;amp;quot;path&amp;amp;quot;&amp;gt;;
            &amp;lt;;em&amp;gt;;${urix.uri}&amp;lt;;/em&amp;gt;;
         &amp;lt;;/span&amp;gt;;
      &amp;lt;;% } %&amp;gt;;
   &amp;lt;;/h1&amp;gt;;

   &amp;lt;;h3&amp;gt;;
      &amp;lt;;span class=&amp;amp;quot;version&amp;amp;quot;&amp;gt;;Version: &amp;lt;;em&amp;gt;;${props.version}&amp;lt;;/em&amp;gt;;&amp;lt;;/span&amp;gt;;
       &amp;lt;;span class=&amp;amp;quot;timestamp&amp;amp;quot;&amp;gt;;Creation: &amp;lt;;em&amp;gt;;${props.timestamp}&amp;lt;;/em&amp;gt;;&amp;lt;;/span&amp;gt;;
   &amp;lt;;/h3&amp;gt;;
&amp;lt;;!-- 
   &amp;lt;;h2 class=&amp;amp;quot;javaClass&amp;amp;quot;&amp;gt;;Java Class: &amp;lt;;em&amp;gt;;${service.controller.type}&amp;lt;;/em&amp;gt;;&amp;lt;;/h2&amp;gt;; --&amp;gt;;
&amp;lt;;/div&amp;gt;;

&amp;lt;;% service.controller.methods.each{ method-&amp;gt;; %&amp;gt;;
   &amp;lt;;div class=&amp;amp;quot;method&amp;amp;quot;&amp;gt;;
      &amp;lt;;h3 class=&amp;amp;quot;httpMethod&amp;amp;quot;&amp;gt;;${method.requestMethod}&amp;lt;;/h3&amp;gt;;
      &amp;lt;;p class=&amp;amp;quot;methodJsDoc&amp;amp;quot;&amp;gt;;${method.javadoc}&amp;lt;;/p&amp;gt;;
      &amp;lt;;% if(method.pathParams.size()&amp;gt;;0 || method.restParams.size() &amp;gt;;0 || method.requestParams.size()&amp;gt;;0 ){ %&amp;gt;;
         &amp;lt;;div class=&amp;amp;quot;input&amp;amp;quot;&amp;gt;;
            &amp;lt;;h3&amp;gt;;Request input&amp;lt;;/h3&amp;gt;;
            &amp;lt;;table class=&amp;amp;quot;topLevel methodDetails&amp;amp;quot;&amp;gt;;
               &amp;lt;;thead&amp;gt;;
               &amp;lt;;tr&amp;gt;;
                  &amp;lt;;th&amp;gt;;Name&amp;lt;;/th&amp;gt;;
                  &amp;lt;;th&amp;gt;;Description&amp;lt;;/th&amp;gt;;
                  &amp;lt;;th&amp;gt;;Param Type&amp;lt;;/th&amp;gt;;
               &amp;lt;;/tr&amp;gt;;
               &amp;lt;;/thead&amp;gt;;
               &amp;lt;;tbody&amp;gt;;
               &amp;lt;;% method.pathParams.each{ parameter-&amp;gt;; %&amp;gt;;
                  &amp;lt;;tr&amp;gt;;
                     &amp;lt;;td class=&amp;amp;quot;name&amp;amp;quot;&amp;gt;;
                           ${parameter.type} ${parameter.name}
                     &amp;lt;;/td&amp;gt;;
                     &amp;lt;;td class=&amp;amp;quot;javadoc&amp;amp;quot;&amp;gt;;
                           ${parameter.javadoc}
                     &amp;lt;;/td&amp;gt;;
                     &amp;lt;;td class=&amp;amp;quot;path&amp;amp;quot;&amp;gt;;
                        Path (Mandatory)
                     &amp;lt;;/td&amp;gt;;
                  &amp;lt;;/tr&amp;gt;;
               &amp;lt;;% } %&amp;gt;;
               &amp;lt;;% method.restParams.each{ parameter-&amp;gt;; %&amp;gt;;
                  &amp;lt;;tr&amp;gt;;
                     &amp;lt;;td class=&amp;amp;quot;name&amp;amp;quot;&amp;gt;;
                           ${parameter.type} ${parameter.name}&amp;lt;;/td&amp;gt;;
                     &amp;lt;;td class=&amp;amp;quot;javadoc&amp;amp;quot;&amp;gt;;
                           ${parameter.javadoc}&amp;lt;;/td&amp;gt;;
                     &amp;lt;;td class=&amp;amp;quot;path&amp;amp;quot;&amp;gt;;
                        REST
                     &amp;lt;;/td&amp;gt;;
                  &amp;lt;;/tr&amp;gt;;
               &amp;lt;;% } %&amp;gt;;
			&amp;lt;;% method.requestParams.each{ parameter-&amp;gt;; %&amp;gt;;
                  &amp;lt;;tr&amp;gt;;
                     &amp;lt;;td class=&amp;amp;quot;name&amp;amp;quot;&amp;gt;;
                           ${parameter.type} ${parameter.name}&amp;lt;;/td&amp;gt;;
                     &amp;lt;;td class=&amp;amp;quot;javadoc&amp;amp;quot;&amp;gt;;
                           ${parameter.javadoc}&amp;lt;;/td&amp;gt;;
                     &amp;lt;;td class=&amp;amp;quot;path&amp;amp;quot;&amp;gt;;
                        Request
                        &amp;lt;;% if(parameter.required){ %&amp;gt;;
                           (Mandatory)
                        &amp;lt;;% }else{ %&amp;gt;;
                           (Optional)
                        &amp;lt;;% } %&amp;gt;;
                        &amp;lt;;% if(parameter.defaultValue){ %&amp;gt;;
                           (Default=${parameter.defaultValue})
                        &amp;lt;;% } %&amp;gt;;
                     &amp;lt;;/td&amp;gt;;
                  &amp;lt;;/tr&amp;gt;;
               &amp;lt;;% } %&amp;gt;;
               &amp;lt;;/tbody&amp;gt;;
            &amp;lt;;/table&amp;gt;;
         &amp;lt;;/div&amp;gt;;
      &amp;lt;;% } %&amp;gt;;
	&amp;lt;;% if( method.responseParams.size()&amp;gt;;0){ %&amp;gt;;
         &amp;lt;;div class=&amp;amp;quot;response&amp;amp;quot;&amp;gt;;
            &amp;lt;;h3&amp;gt;;Response contents&amp;lt;;/h3&amp;gt;;
            &amp;lt;;table class=&amp;amp;quot;topLevel methodDetails&amp;amp;quot;&amp;gt;;
               &amp;lt;;thead&amp;gt;;
               &amp;lt;;tr&amp;gt;;
                  &amp;lt;;th class=&amp;amp;quot;type&amp;amp;quot;&amp;gt;;Response Type&amp;lt;;/th&amp;gt;;
                  &amp;lt;;th class=&amp;amp;quot;description&amp;amp;quot;&amp;gt;;Description&amp;lt;;/th&amp;gt;;
               &amp;lt;;/tr&amp;gt;;
               &amp;lt;;/thead&amp;gt;;
               &amp;lt;;tbody&amp;gt;;
               &amp;lt;;% method.responseParams.each{ parameter-&amp;gt;; %&amp;gt;;
                  &amp;lt;;tr&amp;gt;;
                     &amp;lt;;td class=&amp;amp;quot;type&amp;amp;quot;&amp;gt;;${parameter.type}&amp;lt;;/td&amp;gt;;
                     &amp;lt;;td class=&amp;amp;quot;javadoc&amp;amp;quot;&amp;gt;;${parameter.javadoc}&amp;lt;;/td&amp;gt;;
                  &amp;lt;;/tr&amp;gt;;
               &amp;lt;;% } %&amp;gt;;
               &amp;lt;;/tbody&amp;gt;;
            &amp;lt;;/table&amp;gt;;
         &amp;lt;;/div&amp;gt;;
      &amp;lt;;% } %&amp;gt;;
   &amp;lt;;/div&amp;gt;;
&amp;lt;;% } %&amp;gt;;

ref) http://mestachs.wordpress.com/2012/08/06/rest-api-documentation/

bloging test

2012/08/23

email sending test

notice

2012/08/23

class codetest{ String test; }
link testdel test
test end

this is
my simple note