= Liquidե졼Ȥäץꥱκ
ǤLiquidե졼Ȥäץ륢ץꥱκޤ[[BR]]
ΤAjax+CometȤäꥢ륿åȥӥǤ[[BR]]
http://sourceforge.jp/projects/liquid/

== Action饹ƥץ졼Ȥκ
ޤ˥åȥڡɽ뤿Action饹ƥץ졼Ȥޤ[[BR]]
=== Action饹
LiquidǤAction饹POJOǺ뤿ᡢñActionǤΥ饹ηѾ󥿡եμɬפȤޤ[[BR]]

{{{
 package chat.action;
 
 public class ChatAction
 {
    public String index()
    {
       return "index.ftl";
    }
 }
}}}

᥽åɤ1ĺƤޤˤĤƤϸҤޤAction饹ȥ᥽åɤδط򤷤ޤ礦[[BR]]
LiquidǥեȤWebƥʤǤURLβ褬Τ褦˹Ԥޤ[[BR]]
 http://xxx.xxx/(ץ饰Х̾)/(Action饹̾)/(᥽å̾)
Τ褦˥줿URLΥѥץ饰Х̾(plugin.xmlιޤ)Action饹̾᥽å̾ФŪAction饹ƤӽФȤߤˤʤäƤޤ[[BR]]
ǤΤǺChatAction饹Ǥ/ChatAction/indexȤѥǥˤꡢChatAction饹index()ƤӽФޤ[[BR]]
Action饹ˤϼͳ᥽åɤꤢޤ󤬡URLˤꥢ᥽åɤͤ˥ƥץ졼̾ꤹɬפޤ[[BR]]
ǻꤵ줿ƥץ졼Ȥ᥽åɤθƤӽФɽΤǡϤΥƥץ졼index.ftlޤ礦[[BR]]
=== ƥץ졼
{{{
 <html>
 <body>
 <p>Liquid</p>
 </body>
 </html>
}}}

LiquidǤϥǥեȤ[[FreeMarker:http://freemarker.sourceforge.net/]]ƥץ졼ȥ󥸥ͭˤʤäƤޤΤǡFreeMarkerεˡѤǽǤ[[BR]]
Ȥꤢξ֤ɽ뤫LiquidưƳǧޤ礦ǤLiquidεưˡޤ[[BR]]

== Liquidεưɬפʤ

Liquidưˤϡץ饰⥸塼module.xmlȥץ饰Τplugin.xmlɬפǤ[[BR]]
=== module.xmlκ
ޤmodule.xmlޤ礦[[BR]]

{{{
 <?xml version="1.0" encoding="euc-jp"?>
 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
 <beans>
 
     <bean id="moduleManager" class="jp.maru.liquid.kernel.ModuleManager">
         <property name="modules" >
             <list>
                 <bean id="httpTemplateServerModule"
                 class="jp.maru.liquid.kernel.modules.HttpServerModule">
                     <property name="connector" ref="defaultConnector" />
                     <property name="strategy">
                         <bean class="jp.maru.liquid.kernel.modules.strategy.HttpTemplateStrategy" />
                     </property>
                 </bean>
 
                 <bean id="asyncHttpTemplateServerModule"
                 class="jp.maru.liquid.kernel.modules.AsyncHttpServerModule">
                     <property name="connector" ref="defaultConnector" />
                     <property name="strategy">
                         <bean class="jp.maru.liquid.kernel.modules.strategy.HttpBasicStrategy" />
                     </property>
                 </bean>
             </list>
         </property>
     </bean>

     <bean id="defaultConnector"
      class="jp.maru.liquid.kernel.modules.http.HttpConnector">
         <property name="port" value="80" />
     </bean>
 </beans>
}}

ChatץꥱǤϥåȥڡɽƱȯ/ɽȯΤǡ줾HttpServerModuleAsyncHttpServerModuleɤޤåȥڡǤϥƥץ졼ȽȯΤǥȥƥȤHttpTemplateStrategyƱǤϥƥץ졼ȽɬפʤΤHttpBasicStrategy򤷤Ƥޤ[[BR]]
=== plugin.xmlκ
plugin.xmlޤ

{{{
 <?xml version="1.0" encoding="euc-jp"?>
 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
 <beans>
 
     <bean id="pluginManager" class="jp.maru.liquid.kernel.PluginManager">
         <property name="plugins">
             <list>
                 <ref local="chatActionPlugin" />
             </list>
         </property>
     </bean>
 
     <bean id="chatActionPlugin"
      class="jp.maru.liquid.core.plugins.HttpActionPlugin">
         <property name="bindURI" value="/chat/*" />
         <property name="encoding" value="utf-8" />
         <property name="templatePath" value="/chat/www/" />
         <property name="actionClass" value="chat.action.*Action" />
     </bean>
 
 </beans>
}}}

ȼΥץ饰ȤLiquidȤ߹ޤƤHttpActionPluginȤAction饹ȥƥץ졼ȤΤߤWebץꥱǽǤ[[BR]]
HttpActionPlugin˰ʲΥץѥƥꤷޤ[[BR]]
-bindURI - URL˥Хɤ̾ҤΥץ饰Х̾Action¹Ԥˤϡ/xxx/*פȺǸ磻ɥɤˤɬפޤ
-encoding - HTTPإåcharsetѥ᡼Υ󥳡ɤ˻Ѥʸɡ
-templatePath - ƥץ졼Ȥ֤Ƥ١Υǥ쥯ȥѥ
-actionClass - URLؤΥ˸ƤӽФAction饹̾磻ɥɤˤǽ

=== ե
ߤޤǤ˺ե֤ޤ/chatȤǥ쥯ȥȤޤ[[BR]]
ޤɬפȤʤ륵֥ǥ쥯ȥʲΤ褦˺ޤ礦[[BR]]
{{{
 /chat
   /lib
   /src  
   /www 
   /classes
}}}
LiquidΥ֤Ÿliquid.jarڤlibʲjarե/chat/lib졢run.sh/chatذưޤ[[BR]]
ۤɺChatAction.java/chat/srcˡindex.ftl/chat/wwwˡmodule.xmlplugin.xml/chat֤ޤ[[BR]]

=== ѥ
֤νäChatAction.java򥳥ѥ뤷classե/chat/classesذưޤ[[BR]]
Action饹Ǥϰ¸ѥå̵ᡢä˥饹ѥλ̵ǥѥ뤬ԤޤLiquid¾Υѥå򻲾ȤŬ饹ѥꤷƥѥ뤷ޤ礦[[BR]]

=== ư
Liquidεưrun.shȤޤñrun.sh¹ԤǵưϤǤ[[BR]]
ưǧ褿http://xxx.xxx/chat/Chat/index˥ƤߤƲȥڡɽޤ

== ץ饰κ
åȥڡκǤLiquidȹߤΥץ饰ȤäΤǡ˥ץ饰ɬפ̵äǤƱ˥åȥåɤ߹ˤϤѤνɬפˤʤΤǥץ饰ޤ[[BR]]
CometǤϥΥ֥å̿Ԥɬפ뤿ᡢץ饰ǤϥΥ֥å̿б⥸塼AsyncHttpServerModuleѤޤAsyncHttpServerModuleȤˤAsyncHttpServerPlugin󥿡եɬפޤ[[BR]]
ޤΥץ饰Ǥϥƥץ졼ȤϻѤʤΤǥȥƥHttpBasicStrategyȤޤHttpBasicStrategyǥץ饰ˤHttpBasicPlugin󥿡եޤ[[BR]]

{{{
 package chat.plugin;
 
 import java.util.List;
 import java.util.ArrayList;
 import java.io.IOException;
 
 import jp.maru.liquid.plugin.http.HttpRequest;
 import jp.maru.liquid.plugin.http.HttpResponse;
 import jp.maru.liquid.plugin.http.AsyncHttpEvent;
 import jp.maru.liquid.plugin.http.AsyncTrigger;
 import jp.maru.liquid.plugin.AsyncHttpServerPlugin;
 import jp.maru.liquid.plugin.HttpBasicPlugin;
 
 public class ChatPlugin implements AsyncHttpServerPlugin,HttpBasicPlugin
 {
     private List<AsyncTrigger> _triggerList=new ArrayList<AsyncTrigger>();
     private String _lastMessage;
     private String _bindURI;
 
     @Override
     public void init()
     {
     }
 
     @Override
     public void execute(HttpRequest request,HttpResponse response)
     throws IOException
     {
         response.setContentType("text/html; charset=UTF-8");
         response.getWriter().println(_lastMessage != null? _lastMessage: "");
     }
 
     @Override
     public void httpConnected(AsyncHttpEvent event,AsyncTrigger trigger)
     {
 
         _triggerList.add(trigger);
     }
 
     @Override
     public void httpDisconnected(AsyncHttpEvent event)
     {
     }
 
     public synchronized void message(String handle,String message)
     {
         try
         {
             _lastMessage=handle+": "+message;
 
             for(AsyncTrigger trigger : _triggerList)
                 trigger.resume();
             _triggerList.clear();
             _lastMessage=null;
         }
         catch(IOException ioe)
         {
             ioe.printStackTrace();
         }
     }
 
     @Override
     public String getBindURI()
     {
         return _bindURI;
     }
 
     public void setBindURI(String uri)
     {
         _bindURI=uri;
     }
 }
}}}

󥿡եAsyncHttpServerPluginˤ³˥뤵᥽åhttpConnected()ǻ˥뤵᥽åhttpDisconnected()Ƥ뤿ᡢ줾Ԥޤ[[BR]]
httpConnected()Ǥ³ԤäƤ饤ȤΥ֥AsyncTriggerץ饰ChatPluginΥ󥹥ѿȤѰդListɲäƤԤäƤޤhttpDisconnected()ǤϽԤޤ[[BR]]
󥿡եHttpBasicPluginˤϥ᥽åexecute()ƤΤǤޤΥ᥽åɤǤϥץ饰Ϥ줿åȥå򥯥饤ȤԤޤ[[BR]]
᥽åmessage()ǤϸҤAction饹θƤӽФơ饤ȤƤåץ饰Υ󥹥ѿ¸ListϿƤ륯饤ȤФƤԤäƤޤ[[BR]]
Υ饹AsyncTriggerΥ᥽åresume()ˤꡢߤƤ饤ȤΥꥯȤƳ饤˥᥽åexecute()ƤӽФޤ[[BR]]
ץ饰ϤǴǤ˥饤ȤΥåAction饹ɲäޤ礦

== Action饹ν
饤ȤAjaxˤȯ˥ϥɥ롢åͤˤ뤿ᡢơΥѥ᡼Ǥ褦ѹޤLiquidWebƥʤǤϥѥ᡼setȤ᥽åɤˤΤǡsetHandle()setMsg()Ȥ᥽åɤޤ[[BR]]
äȯμƱѰդChatPluginΥ᥽åmessage()ФȯƤݥȤ褦ˤ⤷ޤ礦[[BR]]

{{{
 package chat.action;
 
 import jp.maru.liquid.plugin.Plugin;
 import jp.maru.liquid.core.plugins.http.annotation.Intercept;
 import jp.maru.liquid.core.plugins.http.annotation.InjectPlugin;
 import jp.maru.liquid.core.plugins.http.interceptor.PluginInterceptor;
 import jp.maru.liquid.core.plugins.http.interceptor.PluginAware;
 import chat.plugin.ChatPlugin;
 
 @Intercept(PluginInterceptor.class)
 @InjectPlugin(ChatPlugin.class)
 public class ChatAction implements PluginAware
 {
     private ChatPlugin _chatPlugin;
     private String _handle,_msg;
 
     public String index()
     {
         return "index.ftl";
     }
 
     public String jquery()
     {
         return "jquery.min.js";
     }
 
     public String msg()
     {
         _chatPlugin.message(_handle,_msg);
 
         return "dummy.ftl";
     }
 
 
     public void setHandle(String handle)
     {
         _handle=handle;
     }
 
     public void setMsg(String msg)
     {
         _msg=msg;
     }
 
     @Override
     public void setPlugin(Plugin[] plugins)
     {
         _chatPlugin=(ChatPlugin)plugins[0];
     }
 }
}}}
 
饹ФƥΥơ@Intercept@InjectPluginꤷƤޤ[[BR]]
Υơ@InterceptϤAction˥ꥯȤ夹˽륤󥿡ץꤷޤϥץ饰򥤥󥸥ȤΤǡPluginInterceptorꤷƤޤ[[BR]]
Υơ@InjectPluginϥ󥸥Ȥץ饰̾ꤷޤ[[BR]]
ΥΥơˤꥤ󥿡ץActionsetPlugin̤ŪΥץ饰򥤥󥸥ȤActionľܥץ饰إǽˤʤޤ[[BR]]
ActionνϤǴλǤϥƥץ졼Ȥޤ礦[[BR]]

== ƥץ졼Ȥν
ƥץ졼ȤǤϥåȤȯȯΥɤФΤǡͳ˺äƤäƹޤ[[BR]]
jQueryȤAjax̿ʬƤޤjQueryΥ饤֥jquery.min.js/chat/www֤ޤ礦[[BR]]

{{{
 <html>
 <head>
 <style type="text/css">
 <!--
 body > * {
     font-size:0.8em;
 }
 #chat {
     width:420px;
     height:250px;
     border:2px solid #FA5;
     overflow:auto;
     margin-top:10px;
     padding:3px;
 }
 
 #handle,#msg {
     border:2px solid #F75;
 }
 -->
 </style>
 </head>
 <body>
 <p>Liquid Sample - Comet Chat</p>
 
 <input type="text" id="handle" size="15"><input type="text" id="msg" size="40">
 <br>
 
 <div id="chat"></div>
 
 <script type="text/javascript" src="/chat/Chat/jquery"></script>
 <script type="text/javascript">
 <!--
 $(document).ready(function()
 {
     $("#msg").keypress(checkReturn);
     waitResponse();
 });
 
 function sendMsg()
 {
     $.get("/chat/Chat/msg",{handle:$("#handle").val(),msg:$("#msg").val()});
     $("#msg").val("");
 }
 
 function waitResponse()
 {
     $.get("/chatComet/",function(response){
         if(response.length > 0)
             $("#chat").html(response+"<br>"+$("#chat").html());
         waitResponse();
     });
 }
 
 function checkReturn(event)
 {
     var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
     if(keyCode==13)
         sendMsg();
 }
 
 //-->
 </script>
 </body>
 </html>
}}}

ǥץ饰ϤȤꤢλǤǸplugin.xmlν򤷤ޤ礦

== plugin.xmlν
ۤɺäChatPluginplugin.xmlϿޤ[[BR]]
ʲƤ˽񤭴Ʋ[[BR]]

{{{
 <?xml version="1.0" encoding="euc-jp"?>
 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
 <beans>
 
     <bean id="pluginManager" class="jp.maru.liquid.kernel.PluginManager">
         <property name="plugins" >
             <list>
                 <ref local="chatPlugin" />
                 <ref local="chatActionPlugin" />
             </list>
         </property>
     </bean>
 
     <bean id="chatPlugin"
      class="chat.plugin.ChatPlugin">
         <property name="bindURI" value="/chatComet/" />
     </bean>
 
     <bean id="chatActionPlugin"
      class="jp.maru.liquid.core.plugins.HttpActionPlugin">
         <property name="bindURI" value="/chat/*" />
         <property name="encoding" value="utf-8" />
         <property name="templatePath" value="/chat/www/" />
         <property name="actionClass" value="chat.action.*Action" />
     </bean>
 
 </beans>
}}}

== ѥ롢¹
˥饹äΤǥѥԤޤ/chat/libȤ򥯥饹ѥ˲äƥѥ뤷ޤ礦[[BR]]
ʤѥ뤬λ顢run.shˤäLiquidưޤ[[BR]]
http://xxx.xxx/chat/Chat/index˥ƥåȤǤ[[BR]]
== ޤȤ
LiquidϷ̤ʥե졼Ǥ⤤ĥäƤޤ[[BR]]
ǽץ饰Ȥ󶡤ˤꥪ֥ȴ֤ΰ¸㤯ƥʥ⤯ѲǽʥƥιۤŪȤƺޤ[[BR]]
ϿޤǤ¾ñμ¹ԲǽPlugin򥵥ݡȤExecuteModule³ؤHibernateΥݡȡΥơˤХǡʤɤεǽܤƤޤ[[BR]]
WebץꥱΤߤʤ餺ХɥץꥱۤΤˤŬե졼ʤΤǳѤƤ館ФȻפޤ[[BR]]
ǤϤ褤Liquid饤դ

