--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> \r
+<HTML>\r
+<HEAD>\r
+ <TITLE>Jigsaw 2.0 Internal design</TITLE>\r
+ <link rel="stylesheet" type="text/css" href="../style/doc.css">\r
+ <LINK rel="Stylesheet" media="screen" type="text/css"\r
+ href="style-font-lock.css"> \r
+</HEAD>\r
+<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">\r
+ <body bgcolor="#FFFFFF">\r
+ <div class="icons-w3c">\r
+ <a href="../../../">\r
+ <img src="/Icons/w3c_home" \r
+ border="0" \r
+ alt="W3C logo"\r
+ height="48" \r
+ width="72">\r
+ </a>\r
+ </div>\r
+ <div class="icons-jigsaw">\r
+ <a href="../../">\r
+ <img src="/Icons/jigsaw" \r
+ border="0"\r
+ alt="Jigsaw"\r
+ height="49"\r
+ width="212">\r
+ </a>\r
+ </div>\r
+\r
+ <div class="title">\r
+ <H1 class="title">\r
+ Jigsaw<br>\r
+ <span class="subtitle">Resource tutorial</span>\r
+ </H1>\r
+ <hr NOSHADE width="70%" align="left">\r
+ <a href="../../Overview.html">Jigsaw Home</a> /\r
+ <a href="../Overview.html">Documentation Overview</a> /\r
+ <a href="Tutorials.html">Tutorials</a>\r
+ </div>\r
+ <div class="body">\r
+<P>\r
+ This tutorial explains you how to write a new resource, by walking\r
+through a complete example. It is assumed that you are familiar with\r
+<A HREF="../User/architecture.html">Jigsaw architecture</A>, and that you\r
+have understand the <A HREF="../User/configuration.html">configuration\r
+tutorial.</A>\r
+<P>\r
+The resource we will write here will be the\r
+<A HREF="../Reference/org.w3c.tools.resources.PassDirectory.html">PassDirectory</A>.\r
+The tutorial will go through the following steps:\r
+<p>\r
+<OL>\r
+ <LI>\r
+ <A HREF="#writing-frame-class">writing the resource class,</A>\r
+ <LI>\r
+ <A HREF="#installing">installing and configuring it.</A>\r
+</OL>\r
+<H1>\r
+ <A NAME="writing-frame-class"></A>Writing the resource class\r
+</H1>\r
+<P>\r
+Before actually writing a new resource, some decisions must be made about:\r
+<p>\r
+<OL>\r
+ <LI>\r
+ <A HREF="#super-class">What will be its super class</A>\r
+ <LI>\r
+ <A HREF="#package">In what package should it go</A>\r
+ <LI>\r
+ <A HREF="#attributes">What attribute should it define</A>\r
+ <LI>\r
+ <A HREF="#redefining">What method should it redefine</A>\r
+</OL>\r
+<H2>\r
+ <A NAME="super-class"></A>Picking a super class\r
+</H2>\r
+<P>\r
+Deciding for the super class of your resource is a pretty simple process\r
+right now. Here are the rule of thumbs:\r
+<UL>\r
+ <LI>\r
+ If your resource is supposed to wrap a file, then you have to choose\r
+ <A HREF="../Reference/org.w3c.tools.resources.FileResource.html">FileResource</A>\r
+ as your super class.\r
+ <LI>\r
+ If your resource is to wrap a directory, then you have to choose\r
+ <A HREF="../Reference/org.w3c.tools.resources.DirectoryResource.html">org.w3c.tools.resource.DirectoryResource</A>\r
+ (or\r
+ <A HREF="../Reference/org.w3c.jigsaw.resources.DirectoryResource.html">org.w3c.jigsaw.resources.DirectoryResource</A>\r
+ if you need content negotiation)\r
+ <LI>\r
+ If you need to manage children then you probably want to sub-class the\r
+ <A HREF="../Reference/org.w3c.tools.resources.ContainerResource.html">ContainerResource</A>.\r
+ <LI>\r
+ In any other case, you need to pick\r
+ <A HREF="../Reference/org.w3c.tools.resources.FramedResource.html">FramedResource</A>\r
+ as your super class.\r
+</UL>\r
+<P>\r
+Given these short rules, it should be obvious that for our sample resource,\r
+what we want to do is subclass the DirectoryResource. So right now, we can\r
+start writing the following piece of code (we will keep in bold the additional\r
+code we add as we walk through the example): <BR>\r
+Note that we don't know yet were to put this file until we have selected\r
+an appropriate package for our resource.\r
+<DIV CLASS="box">\r
+ <PRE><SPAN class="keyword">import</SPAN> <SPAN class="reference">java</SPAN>.<SPAN class="reference">util</SPAN>.*;\r
+<SPAN class="keyword">import</SPAN> <SPAN class="reference">java</SPAN>.<SPAN class="reference">io</SPAN>.*;\r
+<SPAN class="keyword">import</SPAN> <SPAN class="reference">org</SPAN>.<SPAN class="reference">w3c</SPAN>.<SPAN class="reference">tools</SPAN>.<SPAN class="reference">resources</SPAN>.*;\r
+\r
+<SPAN class="reference">public</SPAN> <SPAN class="keyword">class</SPAN> <SPAN class="function-name">PassDirectory</SPAN> <SPAN class="keyword">extends</SPAN> <SPAN class="reference">org</SPAN>.<SPAN class="reference">w3c</SPAN>.<SPAN class="reference">jigsaw</SPAN>.<SPAN class="reference">resources</SPAN>.<SPAN class="type">DirectoryResource</SPAN> {\r
+\r
+}\r
+</PRE>\r
+</DIV>\r
+<H2>\r
+ <A NAME="package"></A>Selecting a package\r
+</H2>\r
+<P>\r
+There is no particular problem with regard to the package your resource belong\r
+to: <B>Jigsaw </B>impose no constraint on this. The only thing you should\r
+be aware of is your CLASSPATH environment variable. This variable setting\r
+is particularly crucial in <B>Jigsaw</B> since it may impact its security:\r
+you don't want anyone to be able to plug new resource classes in the server\r
+!\r
+<P>\r
+For our sample resource, we don't need to create a new package, let's use\r
+<TT>org.w3c.jigsaw.resources</TT>. We can write in it the following\r
+PassDirectory.java file:\r
+<DIV CLASS="box">\r
+ <PRE><SPAN class="keyword">package</SPAN> <SPAN class="reference">org</SPAN>.<SPAN class="reference">w3c</SPAN>.<SPAN class="reference">jigsaw</SPAN>.<SPAN class="type">resources</SPAN> ;\r
+\r
+<SPAN class="keyword">import</SPAN> <SPAN class="reference">java</SPAN>.<SPAN class="reference">util</SPAN>.*;\r
+<SPAN class="keyword">import</SPAN> <SPAN class="reference">java</SPAN>.<SPAN class="reference">io</SPAN>.*;\r
+<SPAN class="keyword">import</SPAN> <SPAN class="reference">org</SPAN>.<SPAN class="reference">w3c</SPAN>.<SPAN class="reference">tools</SPAN>.<SPAN class="reference">resources</SPAN>.*;\r
+\r
+<SPAN class="reference">public</SPAN> <SPAN class="keyword">class</SPAN> <SPAN class="function-name">PassDirectory</SPAN> <SPAN class="keyword">extends</SPAN> <SPAN class="reference">org</SPAN>.<SPAN class="reference">w3c</SPAN>.<SPAN class="reference">jigsaw</SPAN>.<SPAN class="reference">resources</SPAN>.<SPAN class="type">DirectoryResource</SPAN> {\r
+\r
+}\r
+</PRE>\r
+</DIV>\r
+<H2>\r
+ <A NAME="attributes"></A>Defining the attributes\r
+</H2>\r
+<P>\r
+The next thing we have to figure out, is the list of attributes for our new\r
+frame. The\r
+<A HREF="http://jigsaw.w3.org/Doc/Programmer/api/org/w3c/jigsaw/resources/DirectoryResource.html">DirectoryResource</A> \r
+already defines a number of attributes (see the\r
+<A HREF="../Reference/Overview.html">reference manual</A>). Defining the\r
+set of attributes of a resource also defines the way the resource will be\r
+configured (since a resource is configured by editing its attribute values).\r
+Here, we want to be able to configure the target directory that will be wrapped\r
+by the resource.\r
+<P>\r
+The directory wrapped by the resource can be described as an editable\r
+<A HREF="http://jigsaw.w3.org/Doc/Programmer/api/org/w3c/tools/resources/FileAttribute.html">FileAttribute</A>,\r
+which has no defaults value.\r
+<P>\r
+Now that we now the attribute our resource is to have, we should declare\r
+it to the AttributeRegistry. This Registry keeps track of all the attributes\r
+of all resource classes. For each class it knows of, it maintains an ordered\r
+list of the attribute it defines. The fact that this list is ordered is\r
+important, since it allows for fast attribute value access (through a simple\r
+indirection in the attribute value array of each resource instance). Attribute\r
+declaration should be done at class initialization time, so we introduce\r
+a static statement in the class, whose purpose is to declare our attribute:\r
+<DIV CLASS="box">\r
+ <PRE><SPAN class="keyword">package</SPAN> <SPAN class="reference">org</SPAN>.<SPAN class="reference">w3c</SPAN>.<SPAN class="reference">jigsaw</SPAN>.<SPAN class="type">resources</SPAN> ;\r
+\r
+<SPAN class="keyword">import</SPAN> <SPAN class="reference">java</SPAN>.<SPAN class="reference">util</SPAN>.*;\r
+<SPAN class="keyword">import</SPAN> <SPAN class="reference">java</SPAN>.<SPAN class="reference">io</SPAN>.*;\r
+<SPAN class="keyword">import</SPAN> <SPAN class="reference">org</SPAN>.<SPAN class="reference">w3c</SPAN>.<SPAN class="reference">tools</SPAN>.<SPAN class="reference">resources</SPAN>.*;\r
+\r
+<SPAN class="reference">public</SPAN> <SPAN class="keyword">class</SPAN> <SPAN class="function-name">PassDirectory</SPAN> <SPAN class="keyword">extends</SPAN> <SPAN class="reference">org</SPAN>.<SPAN class="reference">w3c</SPAN>.<SPAN class="reference">jigsaw</SPAN>.<SPAN class="reference">resources</SPAN>.<SPAN class="type">DirectoryResource</SPAN> {\r
+\r
+ <SPAN class="comment">/**</SPAN>\r
+<SPAN class="comment"> * Attribute index - The target physical directory of this resource.</SPAN>\r
+<SPAN class="comment"> */</SPAN>\r
+ <SPAN class="preprocessor">protected</SPAN> <SPAN class="type">static</SPAN> <SPAN class="type">int</SPAN> <SPAN class="variable-name">ATTR_PASSTARGET</SPAN> = -1 ;\r
+\r
+ <SPAN class="type">static</SPAN> {\r
+ <SPAN class="type">Attribute</SPAN> <SPAN class="variable-name">a</SPAN> = <SPAN class="keyword">null</SPAN> ;\r
+ <SPAN class="type">Class</SPAN> <SPAN class="variable-name">cls</SPAN> = <SPAN class="keyword">null</SPAN> ;\r
+\r
+ <SPAN class="comment">// Get a pointer to our class.</SPAN>\r
+ <SPAN class="keyword">try</SPAN> {\r
+ cls = Class.forName("<SPAN class="string">org.w3c.jigsaw.resources.PassDirectory</SPAN>") ;\r
+ } <SPAN class="keyword">catch</SPAN> (<SPAN class="type">Exception</SPAN> <SPAN class="variable-name">ex</SPAN>) {\r
+ ex.printStackTrace() ;\r
+ System.exit(1) ;\r
+ }\r
+ <SPAN class="comment">// The directory attribute.</SPAN>\r
+ a = <SPAN class="keyword">new</SPAN> <SPAN class="type">FileAttribute</SPAN>("<SPAN class="string">pass-target</SPAN>"\r
+ , <SPAN class="keyword">null</SPAN>\r
+ , Attribute.EDITABLE);\r
+ ATTR_PASSTARGET = AttributeRegistry.registerAttribute(cls, a) ;\r
+ }\r
+}\r
+</PRE>\r
+</DIV>\r
+<H2>\r
+ <A NAME="redefining"></A>Redefining some methods\r
+</H2>\r
+<P>\r
+At this point, we have declared the set of attributes that our resource defines,\r
+the attribute Registry knows about it, we can now focus on the actual behavior\r
+of the resource. The only difference between PassDirectory and DirectoryResource\r
+is that PassDirectory wraps an external directory instead of the inherited\r
+one. <BR>\r
+In this case, we have to redefine the followings method of\r
+<A HREF="http://jigsaw.w3.org/Doc/Programmer/api/org/w3c/jigsaw/resources/DirectoryResource.html">DirectoryResource</A>:\r
+<UL>\r
+ <LI>\r
+ <TT>public void setValue(int idx, Object value)</TT>\r
+ <LI>\r
+ <TT>public File getDirectory()</TT>\r
+ <LI>\r
+ <TT>public void initialize(Object values[])</TT>\r
+</UL>\r
+<P>\r
+The actual implementation of these methods is the following:\r
+<DIV CLASS="box">\r
+ <PRE><SPAN class="keyword">package</SPAN> <SPAN class="reference">org</SPAN>.<SPAN class="reference">w3c</SPAN>.<SPAN class="reference">jigsaw</SPAN>.<SPAN class="type">resources</SPAN> ;\r
+\r
+<SPAN class="keyword">import</SPAN> <SPAN class="reference">java</SPAN>.<SPAN class="reference">util</SPAN>.*;\r
+<SPAN class="keyword">import</SPAN> <SPAN class="reference">java</SPAN>.<SPAN class="reference">io</SPAN>.*;\r
+<SPAN class="keyword">import</SPAN> <SPAN class="reference">org</SPAN>.<SPAN class="reference">w3c</SPAN>.<SPAN class="reference">tools</SPAN>.<SPAN class="reference">resources</SPAN>.*;\r
+\r
+<SPAN class="reference">public</SPAN> <SPAN class="keyword">class</SPAN> <SPAN class="function-name">PassDirectory</SPAN> <SPAN class="keyword">extends</SPAN> <SPAN class="reference">org</SPAN>.<SPAN class="reference">w3c</SPAN>.<SPAN class="reference">jigsaw</SPAN>.<SPAN class="reference">resources</SPAN>.<SPAN class="type">DirectoryResource</SPAN> {\r
+\r
+ <SPAN class="comment">/**</SPAN>\r
+<SPAN class="comment"> * Attribute index - The target physical directory of this resource.</SPAN>\r
+<SPAN class="comment"> */</SPAN>\r
+ <SPAN class="preprocessor">protected</SPAN> <SPAN class="type">static</SPAN> <SPAN class="type">int</SPAN> <SPAN class="variable-name">ATTR_PASSTARGET</SPAN> = -1 ;\r
+\r
+ <SPAN class="type">static</SPAN> {\r
+ <SPAN class="type">Attribute</SPAN> <SPAN class="variable-name">a</SPAN> = <SPAN class="keyword">null</SPAN> ;\r
+ <SPAN class="type">Class</SPAN> <SPAN class="variable-name">cls</SPAN> = <SPAN class="keyword">null</SPAN> ;\r
+\r
+ <SPAN class="comment">// Get a pointer to our class.</SPAN>\r
+ <SPAN class="keyword">try</SPAN> {\r
+ cls = Class.forName("<SPAN class="string">org.w3c.jigsaw.resources.PassDirectory</SPAN>") ;\r
+ } <SPAN class="keyword">catch</SPAN> (<SPAN class="type">Exception</SPAN> <SPAN class="variable-name">ex</SPAN>) {\r
+ ex.printStackTrace() ;\r
+ System.exit(1) ;\r
+ }\r
+ <SPAN class="comment">// The directory attribute.</SPAN>\r
+ a = <SPAN class="keyword">new</SPAN> <SPAN class="type">FileAttribute</SPAN>("<SPAN class="string">pass-target</SPAN>"\r
+ , <SPAN class="keyword">null</SPAN>\r
+ , Attribute.EDITABLE);\r
+ ATTR_PASSTARGET = AttributeRegistry.registerAttribute(cls, a) ;\r
+ }\r
+\r
+ <SPAN class="comment">/**</SPAN>\r
+<SPAN class="comment"> * Catch side-effects on pass-target, to absolutize it.</SPAN>\r
+<SPAN class="comment"> * </SPAN><SPAN class="keyword">@param </SPAN><SPAN class="variable-name">idx</SPAN><SPAN class="comment"> The attribute to set.</SPAN>\r
+<SPAN class="comment"> * </SPAN><SPAN class="keyword">@param </SPAN><SPAN class="variable-name">value</SPAN><SPAN class="comment"> The new value.</SPAN>\r
+<SPAN class="comment"> */</SPAN>\r
+\r
+ <SPAN class="reference">public</SPAN> <SPAN class="type">void</SPAN> <SPAN class="function-name">setValue</SPAN>(<SPAN class="type">int</SPAN> <SPAN class="variable-name">idx</SPAN>, <SPAN class="type">Object</SPAN> <SPAN class="variable-name">value</SPAN>) {\r
+ <SPAN class="reference">super</SPAN>.setValue(idx, value);\r
+ <SPAN class="keyword">if</SPAN> ( idx == ATTR_PASSTARGET ) {\r
+ <SPAN class="type">File</SPAN> <SPAN class="variable-name">file</SPAN> = (<SPAN class="type">File</SPAN>) value;\r
+ <SPAN class="keyword">if</SPAN> ( ! file.isAbsolute() ) {\r
+ <SPAN class="comment">// Make it absolute, relative to the server space.</SPAN>\r
+ <SPAN class="type">File</SPAN> <SPAN class="variable-name">abs</SPAN> = <SPAN class="keyword">new</SPAN> <SPAN class="type">File</SPAN>(getServer().getRootDirectory()\r
+ , file.toString());\r
+ values[ATTR_PASSTARGET] = abs;\r
+ values[ATTR_DIRECTORY] = abs;\r
+ }\r
+ }\r
+ }\r
+\r
+ <SPAN class="comment">/**</SPAN>\r
+<SPAN class="comment"> * The getDirectory method now returns the pass-directory.</SPAN>\r
+<SPAN class="comment"> * </SPAN><SPAN class="keyword">@return </SPAN><SPAN class="comment">The pass target location.</SPAN>\r
+<SPAN class="comment"> */</SPAN>\r
+\r
+ <SPAN class="reference">public</SPAN> <SPAN class="type">File</SPAN> <SPAN class="function-name">getDirectory</SPAN>() {\r
+ <SPAN class="keyword">return</SPAN> (<SPAN class="type">File</SPAN>) getValue(ATTR_PASSTARGET, <SPAN class="keyword">null</SPAN>) ;\r
+ }\r
+\r
+ <SPAN class="comment">/**</SPAN>\r
+<SPAN class="comment"> * Make the directory attribute default to the target location.</SPAN>\r
+<SPAN class="comment"> * This is required for classes that rely on the directory attribute to</SPAN>\r
+<SPAN class="comment"> * compute their own attributes.</SPAN>\r
+<SPAN class="comment"> * </SPAN><SPAN class="keyword">@param </SPAN><SPAN class="variable-name">values</SPAN><SPAN class="comment"> The values we should initialized from.</SPAN>\r
+<SPAN class="comment"> */</SPAN>\r
+\r
+ <SPAN class="reference">public</SPAN> <SPAN class="type">void</SPAN> <SPAN class="function-name">initialize</SPAN>(<SPAN class="type">Object</SPAN> <SPAN class="variable-name">values</SPAN>[]) {\r
+ <SPAN class="reference">super</SPAN>.initialize(values);\r
+ <SPAN class="type">File</SPAN> <SPAN class="variable-name">target</SPAN> = getDirectory();\r
+ <SPAN class="keyword">if</SPAN> ( target != <SPAN class="keyword">null</SPAN> ) \r
+ setValue(ATTR_DIRECTORY, target);\r
+ }\r
+}\r
+</PRE>\r
+</DIV>\r
+<H1>\r
+ <A NAME="installing"></A>Installing the resource\r
+</H1>\r
+<P>\r
+After reading the <A HREF="../User/resource.html">Resource configuration\r
+tutorial</A> you will be able to install the PassDirectory.\r
+<P>\r
+The example we have been walking through is probably one of the simplest\r
+one, however, by now, you shouldn't have to write a new resource class but\r
+a <A HREF="writing-frames.html">new frame class</A>, see the\r
+<A HREF="design.html">internal design</A> of Jigsaw.\r
+<P>\r
+Enjoy !\r
+ </div> <!-- body -->\r
+ <div class="footer">\r
+<P>\r
+ <HR noshade WIDTH="100%">\r
+ <a href="mailto:jigsaw@w3.org">Jigsaw Team</a><br>\r
+ <span class="mini">\r
+ $Id: writing-resources.html,v 1.1 2010/06/15 12:22:15 smhuang Exp $\r
+ </span>\r
+ <p class="policyfooter">\r
+ <font size=-1>\r
+ <a href="/Consortium/Legal/ipr-notice.html#Copyright">Copyright</a>\r
+ © 1999 <a href="http://www.w3.org">W3C</a> \r
+ (<a href="http://www.lcs.mit.edu">MIT</a>, \r
+ <a href="http://www.inria.fr/">INRIA</a>, \r
+ <a href="http://www.keio.ac.jp/">Keio</a> ), \r
+ All Rights Reserved. W3C \r
+ <a href="/Consortium/Legal/ipr-notice.html#Legal Disclaimer">\r
+ liability,\r
+ </a>\r
+ <a href="/Consortium/Legal/ipr-notice.html#W3C Trademarks">\r
+ trademark\r
+ </a>, \r
+ <a href="/Consortium/Legal/copyright-documents.html">\r
+ document use \r
+ </a>\r
+ and\r
+ <a href="/Consortium/Legal/copyright-software.html">\r
+ software licensing\r
+ </a> rules apply. Your interactions with this site are in\r
+ accordance with our \r
+ <a href="/Consortium/Legal/privacy-statement.html#Public">\r
+ public\r
+ </a> and \r
+ <a href="/Consortium/Legal/privacy-statement.html#Members">\r
+ Member\r
+ </a>\r
+ privacy statements.</font>\r
+ </div>\r
+</BODY></HTML>\r