Seam SVN: r9326 - trunk/doc/Seam_Reference_Guide/en-US.
by seam-commits@lists.jboss.org
Author: norman.richards(a)jboss.com
Date: 2008-10-14 20:23:15 -0400 (Tue, 14 Oct 2008)
New Revision: 9326
Modified:
trunk/doc/Seam_Reference_Guide/en-US/Components.xml
trunk/doc/Seam_Reference_Guide/en-US/Concepts.xml
Log:
JBSEAM-2563
Modified: trunk/doc/Seam_Reference_Guide/en-US/Components.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Components.xml 2008-10-14 23:41:26 UTC (rev 9325)
+++ trunk/doc/Seam_Reference_Guide/en-US/Components.xml 2008-10-15 00:23:15 UTC (rev 9326)
@@ -17,15 +17,7 @@
of the built in components on your own class using
<literal>@Name</literal>.
</para>
-
- <para>
- Note also that even though all the built in components use a
- qualified name, most of them are aliased to unqualified names by
- default. These aliases specify <literal>auto-create="true"</literal>,
- so you do not need to use <literal>create=true</literal> when
- injecting built-in components by their unqualified name.
- </para>
-
+
<section>
<title>Context injection components</title>
<para>
Modified: trunk/doc/Seam_Reference_Guide/en-US/Concepts.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Concepts.xml 2008-10-14 23:41:26 UTC (rev 9325)
+++ trunk/doc/Seam_Reference_Guide/en-US/Concepts.xml 2008-10-15 00:23:15 UTC (rev 9326)
@@ -545,10 +545,40 @@
<programlisting role="XML"><![CDATA[<factory name="loginAction" scope="STATELESS" value="#{com.jboss.myapp.loginAction}"/>]]></programlisting>
<para>
- All of the built-in Seam components have qualified names, but most of them are aliased to a simple
- name by the <literal>components.xml</literal> file included in the Seam jar.
+ All of the built-in Seam components have qualified names but can be accessed through
+ their unqualified names due to the namespace import feature of Seam.
+ The <literal>components.xml</literal> file included in the Seam JAR defines the following
+ namespaces.
</para>
-
+
+<programlisting><components xmlns="http://jboss.com/products/seam/components">
+
+ <import>org.jboss.seam.core</import>
+ <import>org.jboss.seam.cache</import>
+ <import>org.jboss.seam.transaction</import>
+ <import>org.jboss.seam.framework</import>
+ <import>org.jboss.seam.web</import>
+ <import>org.jboss.seam.faces</import>
+ <import>org.jboss.seam.international</import>
+ <import>org.jboss.seam.theme</import>
+ <import>org.jboss.seam.pageflow</import>
+ <import>org.jboss.seam.bpm</import>
+ <import>org.jboss.seam.jms</import>
+ <import>org.jboss.seam.mail</import>
+ <import>org.jboss.seam.security</import>
+ <import>org.jboss.seam.security.management</import>
+ <import>org.jboss.seam.security.permission</import>
+ <import>org.jboss.seam.captcha</import>
+ <import>org.jboss.seam.excel.exporter</import>
+ <!-- ... --->
+</components>
+</programlisting>
+
+ <para>
+ When attempting to resolve an unqualified name, Seam will check each of those namespaces, in order.
+ You can include additional namespaces in your application's <literal>components.xml</literal> file
+ for application-specific namespaces.
+ </para>
</sect2>
<sect2>
16 years, 1 month
Seam SVN: r9325 - trunk/doc/Seam_Reference_Guide/en-US.
by seam-commits@lists.jboss.org
Author: norman.richards(a)jboss.com
Date: 2008-10-14 19:41:26 -0400 (Tue, 14 Oct 2008)
New Revision: 9325
Modified:
trunk/doc/Seam_Reference_Guide/en-US/Configuration.xml
trunk/doc/Seam_Reference_Guide/en-US/Events.xml
Log:
JBSEAM-3488
Modified: trunk/doc/Seam_Reference_Guide/en-US/Configuration.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Configuration.xml 2008-10-14 23:17:54 UTC (rev 9324)
+++ trunk/doc/Seam_Reference_Guide/en-US/Configuration.xml 2008-10-14 23:41:26 UTC (rev 9325)
@@ -207,76 +207,20 @@
</sect3>
- <sect3>
+ <sect3 id="configuration.filters.rewrite">
<title>URL rewriting</title>
<para> This filter allows Seam to apply URL rewriting for views based on configuration in the
- <literal>pages.xml</literal> file. This filter is not activate by default, but can be activated
+ <literal>pages.xml</literal> file. This filter is not activate by default, but can be
+ activated
by adding the configuration to <literal>components.xml</literal>: </para>
- <programlisting role="XML"><![CDATA[<web:rewrite-filter />]]></programlisting>
+ <programlisting role="XML"><![CDATA[<web:rewrite-filter view-mapping="*.seam"/>]]></programlisting>
- <para>
- Rewriting occurs based on rewrite patterns found for views in <literal>pages.xml</literal>.
- Seam URL rewriting does both incoming and outgoing URL rewriting based on the same pattern.
- Here's a simple pattern:
+
+ <para>The <literal>view-mapping</literal> parameter must match the servlet mapping defined for the Faces Servlet
+ in the <literal>web.xml</literal> file. If ommitted, the rewrite filter assumes
+ the pattern <literal>*.seam</literal>.
</para>
-
-
- <programlisting role="XML"><![CDATA[
-<page view-id="/home.xhtml">
- <rewrite pattern="/home" />
-</page>
-]]></programlisting>
-
- <para>
- In this case, any incoming request for <literal>/home</literal> will be sent to
- <literal>/home.xhtml</literal>. More interestingly,
- any link generated that would normally point to <literal>/home.seam</literal> will
- instead be rewritten as <literal>/home</literal>. Rewrite patterns only match the portion of the URL
- before the query parameters. So, <literal>/home.seam?conversationId=13</literal> and
- <literal>/home.seam?color=red</literal>
- will both be matched by this rewrite rule.
- </para>
-
- <para>
- Rewrite rules can take these query paramters into consideration, as shown with the following rules.
- </para>
- <programlisting role="XML"><![CDATA[
-<page view-id="/home.xhtml">
- <rewrite pattern="/home/{color}" />
- <rewrite pattern="/home" />
-</page>
-]]></programlisting>
-
- <para>
- In this case, an incoming request for <literal>/home/red</literal> will be served as
- if it were a request
- for <literal>/home.seam?color=red</literal>. Similarly, if color is a page parameter an outgoing
- URL that would normally show as <literal>/home.seam?color=blue</literal> would instead
- be output as
- <literal>/home/blue</literal>. Rules are processed in order, so it is important to list
- more specific rules before more general rules.
- </para>
-
- <para>Default Seam query parameters can also be mapped using URL rewriting, allowing for another
- option for hiding Seam's fingerprints.
- In the following example, <literal>/search.seam?conversationId=13</literal> would
- be written as <literal>/search-13</literal>.
- </para>
- <programlisting role="XML"><![CDATA[
-<page view-id="/search.xhtml">
- <rewrite pattern="/search-{conversationId}" />
- <rewrite pattern="/search" />
-</page>
-]]></programlisting>
-
- <para>
- Seam URL rewriting provides simple, bidirectional rewriting on a per-view basis. For more
- complex rewriting rules that cover non-seam components, Seam applications can continue to
- use the org.tuckey URLRewriteFilter or apply rewriting rules at the web server.
- </para>
-
-
</sect3>
<sect3>
Modified: trunk/doc/Seam_Reference_Guide/en-US/Events.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Events.xml 2008-10-14 23:17:54 UTC (rev 9324)
+++ trunk/doc/Seam_Reference_Guide/en-US/Events.xml 2008-10-14 23:41:26 UTC (rev 9325)
@@ -270,6 +270,75 @@
</section>
+ <section>
+ <title>URL rewriting with page parameters</title>
+ <para>
+ Rewriting occurs based on rewrite patterns found for views in <literal>pages.xml</literal>.
+ Seam URL rewriting does both incoming and outgoing URL rewriting based on the same pattern.
+ Here's a simple pattern:
+ </para>
+
+
+ <programlisting role="XML"><![CDATA[
+<page view-id="/home.xhtml">
+ <rewrite pattern="/home" />
+</page>
+]]></programlisting>
+
+ <para>
+ In this case, any incoming request for <literal>/home</literal> will be sent to
+ <literal>/home.xhtml</literal>. More interestingly,
+ any link generated that would normally point to <literal>/home.seam</literal> will
+ instead be rewritten as <literal>/home</literal>. Rewrite patterns only match the portion of the URL
+ before the query parameters. So, <literal>/home.seam?conversationId=13</literal> and
+ <literal>/home.seam?color=red</literal>
+ will both be matched by this rewrite rule.
+ </para>
+
+ <para>
+ Rewrite rules can take these query paramters into consideration, as shown with the following rules.
+ </para>
+ <programlisting role="XML"><![CDATA[
+<page view-id="/home.xhtml">
+ <rewrite pattern="/home/{color}" />
+ <rewrite pattern="/home" />
+</page>
+]]></programlisting>
+
+ <para>
+ In this case, an incoming request for <literal>/home/red</literal> will be served as
+ if it were a request
+ for <literal>/home.seam?color=red</literal>. Similarly, if color is a page parameter an outgoing
+ URL that would normally show as <literal>/home.seam?color=blue</literal> would instead
+ be output as
+ <literal>/home/blue</literal>. Rules are processed in order, so it is important to list
+ more specific rules before more general rules.
+ </para>
+
+ <para>Default Seam query parameters can also be mapped using URL rewriting, allowing for another
+ option for hiding Seam's fingerprints.
+ In the following example, <literal>/search.seam?conversationId=13</literal> would
+ be written as <literal>/search-13</literal>.
+ </para>
+ <programlisting role="XML"><![CDATA[
+<page view-id="/search.xhtml">
+ <rewrite pattern="/search-{conversationId}" />
+ <rewrite pattern="/search" />
+</page>
+]]></programlisting>
+
+ <para>
+ Seam URL rewriting provides simple, bidirectional rewriting on a per-view basis. For more
+ complex rewriting rules that cover non-seam components, Seam applications can continue to
+ use the <literal>org.tuckey URLRewriteFilter </literal>or apply rewriting rules at the web server.
+ </para>
+
+ <para>
+ URL rewriting requires the Seam rewrite filter to be enable. Rewrite filter
+ configuration is discussed in <xref linkend="configuration.filters.rewrite"/>.
+ </para>
+
+ </section>
<section>
<title>Conversion and Validation</title>
16 years, 1 month
Seam SVN: r9324 - in trunk/doc/Seam_Reference_Guide/en-US: images and 1 other directory.
by seam-commits@lists.jboss.org
Author: norman.richards(a)jboss.com
Date: 2008-10-14 19:17:54 -0400 (Tue, 14 Oct 2008)
New Revision: 9324
Modified:
trunk/doc/Seam_Reference_Guide/en-US/Tutorial.xml
trunk/doc/Seam_Reference_Guide/en-US/images/blog.png
Log:
JBSEAM-3488
Modified: trunk/doc/Seam_Reference_Guide/en-US/Tutorial.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Tutorial.xml 2008-10-14 23:14:26 UTC (rev 9323)
+++ trunk/doc/Seam_Reference_Guide/en-US/Tutorial.xml 2008-10-14 23:17:54 UTC (rev 9324)
@@ -2950,29 +2950,27 @@
</mediaobject>
</screenshot>
- <para>TODO</para>
- <para>Look in the <literal>dvdstore</literal> directory.</para>
- </section>
- <section id="hibernate">
- <title>An example of Seam with Hibernate: the Hibernate Booking example</title>
+ <para>The Seam DVD Store demo can be run from <literal>dvdstore</literal> directory,
+ just like the other demo applications.</para>
- <para> The Hibernate Booking demo is a straight port of the Booking demo to an alternative architecture that
- uses Hibernate for persistence and JavaBeans instead of session beans. </para>
-
- <para>TODO</para>
- <para>Look in the <literal>hibernate</literal> directory.</para>
</section>
+
<section id="blog">
- <title>A RESTful Seam application: the Blog example</title>
+ <title>Bookmarkable URLs with the Blog example</title>
<para> Seam makes it very easy to implement applications which keep state on the server-side. However,
server-side state is not always appropriate, especially in for functionality that serves up
- <emphasis>content</emphasis>. For this kind of problem we often need to let the user bookmark pages and
- have a relatively stateless server, so that any page can be accessed at any time, via the bookmark. The Blog
- example shows how to a implement RESTful application using Seam. Every page of the application can be
- bookmarked, including the search results page. </para>
+ <emphasis>content</emphasis>. For this kind of problem we often want to keep
+ application state in the URL so that any page can be accessed at any time through
+ a bookmark. The blog example shows how to a implement an
+ application that supports bookmarking throughout, even on the search results page. This
+ example
+ demonstrates how Seam can manage application state in the URL as well as how Seam can rewrite
+ those URLs to be even
+
+ </para>
<screenshot>
<screeninfo>Blog example</screeninfo>
@@ -2998,41 +2996,39 @@
<example>
<title></title>
<programlisting role="XHTML"><![CDATA[<h:dataTable value="#{blog.recentBlogEntries}" var="blogEntry" rows="3">
- <h:column>
- <div class="blogEntry">
- <h3>#{blogEntry.title}</h3>
- <div>
- <h:outputText escape="false"
- value="#{blogEntry.excerpt==null ? blogEntry.body : blogEntry.excerpt}"/>
- </div>
- <p>
- <h:outputLink value="entry.seam" rendered="#{blogEntry.excerpt!=null}">
- <f:param name="blogEntryId" value="#{blogEntry.id}"/>
- Read more...
- </h:outputLink>
- </p>
- <p>
- [Posted on
- <h:outputText value="#{blogEntry.date}">
- <f:convertDateTime timeZone="#{blog.timeZone}"
- locale="#{blog.locale}" type="both"/>
- </h:outputText>]
-  
- <h:outputLink value="entry.seam">[Link]
- <f:param name="blogEntryId" value="#{blogEntry.id}"/>
- </h:outputLink>
- </p>
- </div>
- </h:column>
+ <h:column>
+ <div class="blogEntry">
+ <h3>#{blogEntry.title}</h3>
+ <div>
+ <s:formattedText value="#{blogEntry.excerpt==null ? blogEntry.body : blogEntry.excerpt}"/>
+ </div>
+ <p>
+ <s:link view="/entry.xhtml" rendered="#{blogEntry.excerpt!=null}" propagation="none"
+ value="Read more...">
+ <f:param name="blogEntryId" value="#{blogEntry.id}"/>
+ </s:link>
+ </p>
+ <p>
+ [Posted on 
+ <h:outputText value="#{blogEntry.date}">
+ <f:convertDateTime timeZone="#{blog.timeZone}" locale="#{blog.locale}" type="both"/>
+ </h:outputText>]
+  
+ <s:link view="/entry.xhtml" propagation="none" value="[Link]">
+ <f:param name="blogEntryId" value="#{blogEntry.id}"/>
+ </s:link>
+ </p>
+ </div>
+ </h:column>
</h:dataTable>]]></programlisting>
</example>
- <para> If we navigate to this page from a bookmark, how does the data used by the
- <literal><h:dataTable></literal> actually get initialized? Well, what happens is that
- the <literal>Blog</literal> is retrieved lazily—"pulled"—when needed, by a Seam
- component named <literal>blog</literal>. This is the opposite flow of control to what is usual in
- traditional web action-based frameworks like Struts. </para>
+ <para> If we navigate to this page from a bookmark, how does the <literal>#{blog.recentBlogEntries}</literal>
+ data used by the <literal><h:dataTable></literal> actually get initialized?
+ The <literal>Blog</literal> is retrieved lazily—"pulled"—when needed, by a Seam
+ component named <literal>blog</literal>. This is the opposite flow of control to what is used in
+ traditional action-based web frameworks like Struts. </para>
<example>
<title></title>
<!-- Can't use code hightlighting with callouts -->
@@ -3122,79 +3118,114 @@
</div>]]></programlisting>
- <para> But when we redirect, we need to include the values submitted with the form as request parameters, to
+ <para> But when we redirect, we need to include the values submitted with the form
+ in the URL
get a bookmarkable URL like
- <literal>http://localhost:8080/seam-blog/search.seam?searchPattern=seam</literal>. JSF does not provide
- an easy way to do this, but Seam does. We use a Seam <emphasis>page parameter</emphasis>, defined in
- <literal>WEB-INF/pages.xml</literal>: </para>
+ <literal>http://localhost:8080/seam-blog/search/</literal>. JSF does not provide
+ an easy way to do this, but Seam does. We use two Seam features
+ to accomplish this: <emphasis>page parameters</emphasis> and <emphasis>URL rewriting</emphasis>.
+ Both are defined in <literal>WEB-INF/pages.xml</literal>: </para>
<example>
<title></title>
<programlisting role="XML"><![CDATA[<pages>
<page view-id="/search.xhtml">
+ <rewrite pattern="/search/{searchPattern}"/>
+ <rewrite pattern="/search"/>
+
<param name="searchPattern" value="#{searchService.searchPattern}"/>
+
</page>
...
</pages>]]></programlisting>
-</example>
+</example>
+
+ <para>
+ The page parameter instructs Seam to link the request parameter named <literal>searchPattern</literal>
+ to the value of <literal>#{searchService.searchPattern}</literal>, both whenever a request for
+ the Search page comes in and whenever a link to the search page is generated. Seam
+ takes responsibility for maintaining the link between URL state and application state, and you,
+ the developer, don't have to worry about it.</para>
+ <para>Without URL rewriting, the URL for a search on the term <literal>book</literal>
+ would be <literal>http://localhost:8080/seam-blog/seam/search.xhtml?searchPattern=book</literal>.
+ This is nice, but Seam can make the URL even simpler using a rewrite rule. The first
+ rewrite rule, for the pattern <literal>/search/{searchPattern}</literal>, says that
+ any time we have have a URL for search.xhtml with a searchPattern request parameter, we can
+ fold that URL into the simpler URL. So,the URL we saw earlier,
+ <literal>http://localhost:8080/seam-blog/seam/search.xhtml?searchPattern=book</literal>
+ can be written instead as <literal>http://localhost:8080/seam-blog/search/book</literal>.
+ </para>
+
+ <para>Just like with page parameters, URL rewriting is bi-directional. That means that Seam
+ forwards requests for the simpler URL to the the right view, and it also automatically generates
+ the simpler view for you. You never need to worry about constructing URLs. It's
+ all handled transparently behind the scenes. The only requirement is that to use URL rewriting,
+ the rewrite filter needs to be enabled in <literal>components.xml</literal>.
+ </para>
+
+
+ <programlisting><web:rewrite-filter view-mapping="/seam/*" /></programlisting>
- <para> This tells Seam to include the value of <literal>#{searchService.searchPattern}</literal> as a
- request parameter named <literal>searchPattern</literal> when redirecting to the page, and then re-apply
- the value of that parameter to the model before rendering the page. </para>
-
<para> The redirect takes us to the <literal>search.xhtml</literal> page: </para>
<programlisting role="XHTML"><![CDATA[<h:dataTable value="#{searchResults}" var="blogEntry">
- <h:column>
- <div>
- <h:outputLink value="entry.seam">
- <f:param name="blogEntryId" value="#{blogEntry.id}"/>
- #{blogEntry.title}
- </h:outputLink>
- posted on
- <h:outputText value="#{blogEntry.date}">
+ <h:column>
+ <div>
+ <s:link view="/entry.xhtml" propagation="none" value="#{blogEntry.title}">
+ <f:param name="blogEntryId" value="#{blogEntry.id}"/>
+ </s:link>
+ posted on
+ <h:outputText value="#{blogEntry.date}">
<f:convertDateTime timeZone="#{blog.timeZone}" locale="#{blog.locale}" type="both"/>
- </h:outputText>
- </div>
- </h:column>
+ </h:outputText>
+ </div>
+ </h:column>
</h:dataTable>]]></programlisting>
- <para> Which again uses "pull"-style MVC to retrieve the actual search results: </para>
+ <para> Which again uses "pull"-style MVC to retrieve the actual search results using
+ Hibernate Search.</para>
<programlisting role="JAVA"><![CDATA[@Name("searchService")
public class SearchService
{
@In
- private EntityManager entityManager;
+ private FullTextEntityManager entityManager;
private String searchPattern;
@Factory("searchResults")
public List<BlogEntry> getSearchResults()
{
- if (searchPattern==null)
- {
- return null;
+ if (searchPattern==null || "".equals(searchPattern) ) {
+ searchPattern = null;
+ return entityManager.createQuery("select be from BlogEntry be order by date desc").getResultList();
}
else
{
- return entityManager.createQuery("select be from BlogEntry be "" +
- "where lower(be.title) like :searchPattern " +
- "lower(be.body) like :searchPattern order by be.date desc")
- .setParameter( "searchPattern", getSqlSearchPattern() )
+ Map<String,Float> boostPerField = new HashMap<String,Float>();
+ boostPerField.put( "title", 4f );
+ boostPerField.put( "body", 1f );
+ String[] productFields = {"title", "body"};
+ QueryParser parser = new MultiFieldQueryParser(productFields, new StandardAnalyzer(), boostPerField);
+ parser.setAllowLeadingWildcard(true);
+ org.apache.lucene.search.Query luceneQuery;
+ try
+ {
+ luceneQuery = parser.parse(searchPattern);
+ }
+ catch (ParseException e)
+ {
+ return null;
+ }
+
+ return entityManager.createFullTextQuery(luceneQuery, BlogEntry.class)
.setMaxResults(100)
.getResultList();
}
}
- private String getSqlSearchPattern()
- {
- return searchPattern==null ? "" :
- '%' + searchPattern.toLowerCase().replace('*', '%').replace('?', '_') + '%';
- }
-
public String getSearchPattern()
{
return searchPattern;
@@ -3205,7 +3236,8 @@
this.searchPattern = searchPattern;
}
-}]]></programlisting>
+}
+]]></programlisting>
</section>
@@ -3225,11 +3257,9 @@
@Scope(STATELESS)
public class EntryAction
{
- @In(create=true)
- private Blog blog;
+ @In Blog blog;
- @Out
- private BlogEntry blogEntry;
+ @Out BlogEntry blogEntry;
public void loadBlogEntry(String id) throws EntryNotFoundException
{
@@ -3245,39 +3275,60 @@
<programlisting role="XML"><![CDATA[<pages>
...
- <page view-id="/entry.xhtml" action="#{entryAction.loadBlogEntry(blogEntry.id)}">
- <param name="blogEntryId" value="#{blogEntry.id}"/>
- </page>
+ <page view-id="/entry.xhtml">
+ <rewrite pattern="/entry/{blogEntryId}" />
+ <rewrite pattern="/entry" />
+
+ <param name="blogEntryId"
+ value="#{blogEntry.id}"/>
+
+ <action execute="#{entryAction.loadBlogEntry(blogEntry.id)}"/>
+ </page>
+
+ <page view-id="/post.xhtml" login-required="true">
+ <rewrite pattern="/post" />
+
+ <action execute="#{postAction.post}"
+ if="#{validation.succeeded}"/>
+
+ <action execute="#{postAction.invalid}"
+ if="#{validation.failed}"/>
+
+ <navigation from-action="#{postAction.post}">
+ <redirect view-id="/index.xhtml"/>
+ </navigation>
+ </page>
- <page view-id="/post.xhtml" action="#{loginAction.challenge}"/>
+ <page view-id="*">
+ <action execute="#{blog.hitCount.hit}"/>
+ </page>
- <page view-id="*" action="#{blog.hitCount.hit}"/>
-
</pages>]]></programlisting>
- <para> Notice that the example is using page actions for some other functionality—the login
- challenge, and the pageview counter. Also notice the use of a parameter in the page action method
- binding. This is not a standard feature of JSF EL, but Seam lets you use it, not just for page actions,
- but also in JSF method bindings. </para>
+ <para> Notice that the example is using page actions for post validation
+ and the pageview counter. Also notice the use of a parameter in the page action method
+ binding. This is not a standard feature of JSF EL, but Seam lets you use it, not just
+ for page actions but also in JSF method bindings. </para>
<para> When the <literal>entry.xhtml</literal> page is requested, Seam first binds the page parameter
- <literal>blogEntryId</literal> to the model, then runs the page action, which retrieves the needed
+ <literal>blogEntryId</literal> to the model. Keep in mind that because of the URL rewriting,
+ the blogEntryId parameter name won't show up in the URL. Seam then runs the page action, which retrieves
+ the needed
data—the <literal>blogEntry</literal>—and places it in the Seam event context.
Finally, the following is rendered: </para>
<programlisting role="XHTML"><![CDATA[<div class="blogEntry">
- <h3>#{blogEntry.title}</h3>
- <div>
- <h:outputText escape="false" value="#{blogEntry.body}"/>
- </div>
- <p>
- [Posted on 
- <h:outputText value="#{blogEntry.date}">
- <f:convertDateTime timezone="#{blog.timeZone}"
- locale="#{blog.locale}" type="both"/>
- </h:outputText>]
- </p>
+ <h3>#{blogEntry.title}</h3>
+ <div>
+ <s:formattedText value="#{blogEntry.body}"/>
+ </div>
+ <p>
+ [Posted on 
+ <h:outputText value="#{blogEntry.date}">
+ <f:convertDateTime timeZone="#{blog.timeZone}" locale="#{blog.locale}" type="both"/>
+ </h:outputText>]
+ </p>
</div>]]></programlisting>
@@ -3313,7 +3364,6 @@
blogEntry = blog.getBlogEntry( blogEntry.getId() );
if (blogEntry==null) throw new EntryNotFoundException(id);
}
-
}]]></programlisting>
<programlisting role="XML"><![CDATA[<pages>
@@ -3329,6 +3379,11 @@
<para> It is a matter of taste which implementation you prefer. </para>
+
+ <para>
+ The blog demo also demonstrates very simple password authentication, posting to
+ the blog, page fragment caching and atom feed generation.
+ </para>
</section>
</section>
Modified: trunk/doc/Seam_Reference_Guide/en-US/images/blog.png
===================================================================
(Binary files differ)
16 years, 1 month
Seam SVN: r9323 - in trunk/seam-gen: view/layout and 1 other directory.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-10-14 19:14:26 -0400 (Tue, 14 Oct 2008)
New Revision: 9323
Modified:
trunk/seam-gen/icefaces/view/layout/template.xhtml
trunk/seam-gen/view/layout/template.xhtml
Log:
oops, #{reqeustPath} should be {request.contextPath}
Modified: trunk/seam-gen/icefaces/view/layout/template.xhtml
===================================================================
--- trunk/seam-gen/icefaces/view/layout/template.xhtml 2008-10-14 23:05:11 UTC (rev 9322)
+++ trunk/seam-gen/icefaces/view/layout/template.xhtml 2008-10-14 23:14:26 UTC (rev 9323)
@@ -12,7 +12,7 @@
doctypeSystem="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>@projectName@</title>
- <link rel="shortcut icon" href="#{requestPath}/favicon.ico"/>
+ <link rel="shortcut icon" href="#{request.contextPath}/favicon.ico"/>
<link rel='stylesheet' type='text/css' href='./xmlhttp/css/rime/rime.css'/>
<link href="stylesheet/theme.css" rel="stylesheet" type="text/css" />
<ui:insert name="head"/>
Modified: trunk/seam-gen/view/layout/template.xhtml
===================================================================
--- trunk/seam-gen/view/layout/template.xhtml 2008-10-14 23:05:11 UTC (rev 9322)
+++ trunk/seam-gen/view/layout/template.xhtml 2008-10-14 23:14:26 UTC (rev 9323)
@@ -11,7 +11,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>@projectName@</title>
- <link rel="shortcut icon" href="#{requestPath}/favicon.ico"/>
+ <link rel="shortcut icon" href="#{request.contextPath}/favicon.ico"/>
<a:loadStyle src="resource:///stylesheet/theme.xcss"/>
<a:loadStyle src="/stylesheet/theme.css"/>
<ui:insert name="head"/>
16 years, 1 month
Seam SVN: r9322 - in trunk/seam-gen: view and 1 other directory.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-10-14 19:05:11 -0400 (Tue, 14 Oct 2008)
New Revision: 9322
Modified:
trunk/seam-gen/icefaces/view/list.xhtml.ftl
trunk/seam-gen/view/list.xhtml.ftl
Log:
include query alias in sort path (to be compliant with JPA)
Modified: trunk/seam-gen/icefaces/view/list.xhtml.ftl
===================================================================
--- trunk/seam-gen/icefaces/view/list.xhtml.ftl 2008-10-14 22:56:40 UTC (rev 9321)
+++ trunk/seam-gen/icefaces/view/list.xhtml.ftl 2008-10-14 23:05:11 UTC (rev 9322)
@@ -92,7 +92,7 @@
<ui:include src="layout/sort.xhtml">
<ui:param name="entityList" value="${'#'}{${listName}}"/>
<ui:param name="propertyLabel" value="${label(componentProperty.name)}"/>
- <ui:param name="propertyPath" value="${propertyPath}"/>
+ <ui:param name="propertyPath" value="${componentName}.${propertyPath}"/>
</ui:include>
</f:facet>
${'#'}{${componentName}.${property.name}.${componentProperty.name}}
@@ -104,7 +104,7 @@
<ui:include src="layout/sort.xhtml">
<ui:param name="entityList" value="${'#'}{${listName}}"/>
<ui:param name="propertyLabel" value="${label(property.name)}"/>
- <ui:param name="propertyPath" value="${property.name}"/>
+ <ui:param name="propertyPath" value="${componentName}.${property.name}"/>
</ui:include>
</f:facet>
${'#'}{${componentName}.${property.name}}&nbsp;
@@ -121,7 +121,7 @@
<ui:include src="layout/sort.xhtml">
<ui:param name="entityList" value="${'#'}{${listName}}"/>
<ui:param name="propertyLabel" value="${label(property.name)} ${label(componentProperty.name)?uncap_first}"/>
- <ui:param name="propertyPath" value="${propertyPath}"/>
+ <ui:param name="propertyPath" value="${componentName}.${propertyPath}"/>
</ui:include>
</f:facet>
${'#'}{${componentName}.${propertyPath}}&nbsp;
@@ -134,7 +134,7 @@
<ui:include src="layout/sort.xhtml">
<ui:param name="entityList" value="${'#'}{${listName}}"/>
<ui:param name="propertyLabel" value="${label(property.name)} ${label(parentPojo.identifierProperty.name)?uncap_first}"/>
- <ui:param name="propertyPath" value="${propertyPath}"/>
+ <ui:param name="propertyPath" value="${componentName}.${propertyPath}"/>
</ui:include>
</f:facet>
${'#'}{${componentName}.${propertyPath}}
Modified: trunk/seam-gen/view/list.xhtml.ftl
===================================================================
--- trunk/seam-gen/view/list.xhtml.ftl 2008-10-14 22:56:40 UTC (rev 9321)
+++ trunk/seam-gen/view/list.xhtml.ftl 2008-10-14 23:05:11 UTC (rev 9322)
@@ -74,7 +74,7 @@
<ui:include src="layout/sort.xhtml">
<ui:param name="entityList" value="${'#'}{${listName}}"/>
<ui:param name="propertyLabel" value="${label(componentProperty.name)}"/>
- <ui:param name="propertyPath" value="${propertyPath}"/>
+ <ui:param name="propertyPath" value="${componentName}.${propertyPath}"/>
</ui:include>
</f:facet>
<@outputValue property=componentProperty expression="${'#'}{_${componentName}.${property.name}.${componentProperty.name}}" indent=12/>
@@ -86,7 +86,7 @@
<ui:include src="layout/sort.xhtml">
<ui:param name="entityList" value="${'#'}{${listName}}"/>
<ui:param name="propertyLabel" value="${label(property.name)}"/>
- <ui:param name="propertyPath" value="${property.name}"/>
+ <ui:param name="propertyPath" value="${componentName}.${property.name}"/>
</ui:include>
</f:facet>
<@outputValue property=property expression="${'#'}{_${componentName}.${property.name}}" indent=12/>
@@ -103,7 +103,7 @@
<ui:include src="layout/sort.xhtml">
<ui:param name="entityList" value="${'#'}{${listName}}"/>
<ui:param name="propertyLabel" value="${label(property.name)} ${label(componentProperty.name)?uncap_first}"/>
- <ui:param name="propertyPath" value="${propertyPath}"/>
+ <ui:param name="propertyPath" value="${componentName}.${propertyPath}"/>
</ui:include>
</f:facet>
<@outputValue property=componentProperty expression="${'#'}{_${componentName}.${propertyPath}}" indent=12/>
@@ -116,7 +116,7 @@
<ui:include src="layout/sort.xhtml">
<ui:param name="entityList" value="${'#'}{${listName}}"/>
<ui:param name="propertyLabel" value="${label(property.name)} ${label(parentPojo.identifierProperty.name)?uncap_first}"/>
- <ui:param name="propertyPath" value="${propertyPath}"/>
+ <ui:param name="propertyPath" value="${componentName}.${propertyPath}"/>
</ui:include>
</f:facet>
<@outputValue property=parentPojo.identifierProperty expression="${'#'}{_${componentName}.${propertyPath}}" indent=12/>
16 years, 1 month
Seam SVN: r9321 - in trunk/src: test/unit/org/jboss/seam/test/unit and 1 other directory.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-10-14 18:56:40 -0400 (Tue, 14 Oct 2008)
New Revision: 9321
Added:
trunk/src/test/unit/org/jboss/seam/test/unit/QueryTest.java
Modified:
trunk/src/main/org/jboss/seam/framework/Query.java
Log:
When creating the count query, replace any "join fetch" operator with "join"
lay the foundation for a JPA-compliant count query, but leave disabled
Modified: trunk/src/main/org/jboss/seam/framework/Query.java
===================================================================
--- trunk/src/main/org/jboss/seam/framework/Query.java 2008-10-14 22:52:15 UTC (rev 9320)
+++ trunk/src/main/org/jboss/seam/framework/Query.java 2008-10-14 22:56:40 UTC (rev 9321)
@@ -28,6 +28,7 @@
public abstract class Query<T, E>
extends PersistenceController<T> //TODO: extend MutableController!
{
+ private static final Pattern SUBJECT_PATTERN = Pattern.compile("^select (\\w+(\\.\\w+)*)\\s+from", Pattern.CASE_INSENSITIVE);
private static final Pattern FROM_PATTERN = Pattern.compile("(^|\\s)(from)\\s", Pattern.CASE_INSENSITIVE);
private static final Pattern WHERE_PATTERN = Pattern.compile("\\s(where)\\s", Pattern.CASE_INSENSITIVE);
private static final Pattern ORDER_PATTERN = Pattern.compile("\\s(order)(\\s)+by\\s", Pattern.CASE_INSENSITIVE);
@@ -283,11 +284,25 @@
throw new IllegalArgumentException("no from clause found in query");
}
int fromLoc = fromMatcher.start(2);
-
+
Matcher orderMatcher = ORDER_PATTERN.matcher(ejbql);
int orderLoc = orderMatcher.find() ? orderMatcher.start(1) : ejbql.length();
- return "select count(*) " + ejbql.substring(fromLoc, orderLoc);
+ Matcher whereMatcher = WHERE_PATTERN.matcher(ejbql);
+ int whereLoc = whereMatcher.find() ? whereMatcher.start(1) : orderLoc;
+
+ String subject = "*";
+ // TODO to be JPA-compliant, we need to make this query like "select count(u) from User u"
+ // however, Hibernate produces queries some databases cannot run when the primary key is composite
+// Matcher subjectMatcher = SUBJECT_PATTERN.matcher(ejbql);
+// if ( subjectMatcher.find() )
+// {
+// subject = subjectMatcher.group(1);
+// }
+
+ return new StringBuilder(ejbql.length() + 15).append("select count(").append(subject).append(") ").
+ append(ejbql.substring(fromLoc, whereLoc).replace("join fetch", "join")).
+ append(ejbql.substring(whereLoc, orderLoc)).toString().trim();
}
public String getEjbql()
Added: trunk/src/test/unit/org/jboss/seam/test/unit/QueryTest.java
===================================================================
--- trunk/src/test/unit/org/jboss/seam/test/unit/QueryTest.java (rev 0)
+++ trunk/src/test/unit/org/jboss/seam/test/unit/QueryTest.java 2008-10-14 22:56:40 UTC (rev 9321)
@@ -0,0 +1,67 @@
+package org.jboss.seam.test.unit;
+
+import org.jboss.seam.framework.EntityQuery;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class QueryTest
+{
+ /**
+ * These tests verify that the count query is properly extracted from the rendered
+ * query. There are two points of focus. The first is that "join fetch" is replaced
+ * with "join" in the where clause. The second is that the subject of the query is
+ * used in the count() function unless the query does not have an explicit subject,
+ * in which case a * is used instead.
+ */
+ @Test
+ public void testCountQuery() {
+ UnitQuery query = new UnitQuery();
+ query.setEjbql("from Person p");
+ query.parseEjbql();
+ assertEquals(query.getCountEjbql(), "select count(*) from Person p");
+
+ query.setEjbql("from Person p where p.location is not null");
+ query.setOrderColumn("username");
+ query.parseEjbql();
+ assertEquals(query.getCountEjbql(), "select count(*) from Person p where p.location is not null");
+
+ query.setEjbql("select p from Person p");
+ query.setOrderColumn("username");
+ query.parseEjbql();
+ // TODO this should eventually become count(p)
+ assertEquals(query.getCountEjbql(), "select count(*) from Person p");
+
+ query.setEjbql("select v from Vehicle v join fetch v.person");
+ query.setOrderColumn("make");
+ query.parseEjbql();
+ // TODO this should eventually become count(v)
+ assertEquals(query.getCountEjbql(), "select count(*) from Vehicle v join v.person");
+
+ query.setEjbql("select v.person from Vehicle v left join fetch v.person");
+ query.parseEjbql();
+ // TODO this should eventually become count(v.person)
+ assertEquals(query.getCountEjbql(), "select count(*) from Vehicle v left join v.person");
+ }
+
+ class UnitQuery extends EntityQuery {
+
+ @Override
+ protected void parseEjbql()
+ {
+ super.parseEjbql();
+ }
+
+ @Override
+ protected String getRenderedEjbql()
+ {
+ return super.getRenderedEjbql();
+ }
+
+ @Override
+ protected String getCountEjbql()
+ {
+ return super.getCountEjbql();
+ }
+
+ }
+}
16 years, 1 month
Seam SVN: r9320 - trunk.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-10-14 18:52:15 -0400 (Tue, 14 Oct 2008)
New Revision: 9320
Modified:
trunk/seam
Log:
make script impervious to spaces
Modified: trunk/seam
===================================================================
--- trunk/seam 2008-10-14 21:57:05 UTC (rev 9319)
+++ trunk/seam 2008-10-14 22:52:15 UTC (rev 9320)
@@ -18,17 +18,17 @@
WORKING_DIR=$PWD
if [ -z "$SEAM_HOME" ]; then
- SEAM_SCRIPT=$0
- SEAM_SCRIPT_TARGET=`readlink $0`
- if [ $? -eq 0 ]; then
- SEAM_SCRIPT=$SEAM_SCRIPT_TARGET
+ if [ -h "$0" ]; then
+ SEAM_SCRIPT=`readlink "$0"`
+ else
+ SEAM_SCRIPT=$0
fi
# get the full path without any relative bits (not really necessary)
- SEAM_SCRIPT_ABS_PATH=`readlink -f $0 2>/dev/null`
+ SEAM_SCRIPT_ABS_PATH=`readlink -f "$0" 2>/dev/null`
if [ $? -eq 0 ]; then
SEAM_SCRIPT=$SEAM_SCRIPT_ABS_PATH
fi
- SEAM_HOME=`dirname $SEAM_SCRIPT`
+ SEAM_HOME=`dirname "$SEAM_SCRIPT"`
fi
SEAM_GEN_DIR="$SEAM_HOME/seam-gen"
@@ -46,11 +46,11 @@
esac
if [ -z "$SEAM_COMMAND" ]; then
- cat $SEAM_GEN_DIR/USAGE
+ cat "$SEAM_GEN_DIR/USAGE"
elif [ "$SEAM_COMMAND" = help ]; then
- cat $SEAM_GEN_DIR/README
+ cat "$SEAM_GEN_DIR/README"
elif $cygwin; then
- java -cp "${JAVA_HOME}\lib\tools.jar;${SEAM_HOME}\build\lib\ant-launcher.jar;${SEAM_HOME}\build\lib\ant-nodeps.jar;${SEAM_HOME}\build\lib\ant.jar" -Dant.home=${SEAM_HOME}\lib org.apache.tools.ant.launch.Launcher -buildfile "${SEAM_GEN_DIR}\build.xml" -Dworking.dir=$WORKING_DIR ${*}
+ java -cp "${JAVA_HOME}\lib\tools.jar;${SEAM_HOME}\build\lib\ant-launcher.jar;${SEAM_HOME}\build\lib\ant-nodeps.jar;${SEAM_HOME}\build\lib\ant.jar" -Dant.home="${SEAM_HOME}\lib" org.apache.tools.ant.launch.Launcher -buildfile "${SEAM_GEN_DIR}\build.xml" -Dworking.dir="$WORKING_DIR" ${*}
else
- java -cp "${JAVA_HOME}/lib/tools.jar:${SEAM_HOME}/build/lib/ant-launcher.jar:${SEAM_HOME}/build/lib/ant-nodeps.jar:${SEAM_HOME}/build/lib/ant.jar" -Dant.home=${SEAM_HOME}/lib org.apache.tools.ant.launch.Launcher -buildfile "${SEAM_GEN_DIR}/build.xml" -Dworking.dir=$WORKING_DIR ${*}
+ java -cp "${JAVA_HOME}/lib/tools.jar:${SEAM_HOME}/build/lib/ant-launcher.jar:${SEAM_HOME}/build/lib/ant-nodeps.jar:${SEAM_HOME}/build/lib/ant.jar" -Dant.home="${SEAM_HOME}/lib" org.apache.tools.ant.launch.Launcher -buildfile "${SEAM_GEN_DIR}/build.xml" -Dworking.dir="$WORKING_DIR" ${*}
fi
16 years, 1 month
Seam SVN: r9319 - trunk.
by seam-commits@lists.jboss.org
Author: dan.j.allen
Date: 2008-10-14 17:57:05 -0400 (Tue, 14 Oct 2008)
New Revision: 9319
Modified:
trunk/seam
Log:
fix script so that it works on mac OSX (w/o gnu tools installed)
Modified: trunk/seam
===================================================================
--- trunk/seam 2008-10-14 20:34:34 UTC (rev 9318)
+++ trunk/seam 2008-10-14 21:57:05 UTC (rev 9319)
@@ -18,15 +18,24 @@
WORKING_DIR=$PWD
if [ -z "$SEAM_HOME" ]; then
- # get the full path (without any relative bits)
- SEAM_SCRIPT=`readlink -f $0`
+ SEAM_SCRIPT=$0
+ SEAM_SCRIPT_TARGET=`readlink $0`
+ if [ $? -eq 0 ]; then
+ SEAM_SCRIPT=$SEAM_SCRIPT_TARGET
+ fi
+ # get the full path without any relative bits (not really necessary)
+ SEAM_SCRIPT_ABS_PATH=`readlink -f $0 2>/dev/null`
+ if [ $? -eq 0 ]; then
+ SEAM_SCRIPT=$SEAM_SCRIPT_ABS_PATH
+ fi
SEAM_HOME=`dirname $SEAM_SCRIPT`
fi
SEAM_GEN_DIR="$SEAM_HOME/seam-gen"
SEAM_COMMAND="${1}"
-echo $SEAM_HOME
+echo "Location of seam script: $SEAM_HOME"
+echo "seam-gen template folder: $SEAM_GEN_DIR"
# OS specific support (must be 'true' or 'false').
cygwin=false;
16 years, 1 month
Seam SVN: r9318 - trunk.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-10-14 16:34:34 -0400 (Tue, 14 Oct 2008)
New Revision: 9318
Modified:
trunk/seam
Log:
use the location of the script not the directory
Modified: trunk/seam
===================================================================
--- trunk/seam 2008-10-14 20:12:08 UTC (rev 9317)
+++ trunk/seam 2008-10-14 20:34:34 UTC (rev 9318)
@@ -15,17 +15,19 @@
exit 1
fi
-DIRNAME=`dirname $0`
WORKING_DIR=$PWD
if [ -z "$SEAM_HOME" ]; then
# get the full path (without any relative bits)
- SEAM_HOME=`readlink -f $DIRNAME`
+ SEAM_SCRIPT=`readlink -f $0`
+ SEAM_HOME=`dirname $SEAM_SCRIPT`
fi
SEAM_GEN_DIR="$SEAM_HOME/seam-gen"
SEAM_COMMAND="${1}"
+echo $SEAM_HOME
+
# OS specific support (must be 'true' or 'false').
cygwin=false;
case "`uname`" in
16 years, 1 month
Seam SVN: r9317 - trunk/doc/Seam_Reference_Guide/en-US.
by seam-commits@lists.jboss.org
Author: pete.muir(a)jboss.org
Date: 2008-10-14 16:12:08 -0400 (Tue, 14 Oct 2008)
New Revision: 9317
Modified:
trunk/doc/Seam_Reference_Guide/en-US/Author_Group.xml
Log:
Add Michael Courcy to translators
Modified: trunk/doc/Seam_Reference_Guide/en-US/Author_Group.xml
===================================================================
--- trunk/doc/Seam_Reference_Guide/en-US/Author_Group.xml 2008-10-14 19:33:27 UTC (rev 9316)
+++ trunk/doc/Seam_Reference_Guide/en-US/Author_Group.xml 2008-10-14 20:12:08 UTC (rev 9317)
@@ -1,11 +1,10 @@
<?xml version="1.0" standalone="no"?>
+<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+]>
<authorgroup>
<author>
<firstname>Gavin</firstname>
<surname>King</surname>
- <affiliation>
- <shortaffil>Project Lead</shortaffil>
- </affiliation>
</author>
<author>
<firstname>Pete</firstname>
@@ -90,8 +89,16 @@
<firstname>Steve</firstname>
<surname>Ebersole</surname>
</othercredit>
+ <othercredit>
+ <firstname>Michael</firstname>
+ <surname>Courcy</surname>
+ <affiliation>
+ <shortaffil>French Translation</shortaffil>
+ </affiliation>
+ </othercredit>
<editor>
<firstname>Samson</firstname>
<surname>Kittoli</surname>
</editor>
+
</authorgroup>
16 years, 1 month