[jboss-cvs] JBossBlog SVN: r227 - in trunk: resources and 22 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Feb 28 08:36:54 EST 2008


Author: adamw
Date: 2008-02-28 08:36:54 -0500 (Thu, 28 Feb 2008)
New Revision: 227

Added:
   trunk/src/action/org/jboss/blog/session/feed/mod/PostsValidator.java
   trunk/src/shotoku/
   trunk/src/shotoku/org/
   trunk/src/shotoku/org/jboss/
   trunk/src/shotoku/org/jboss/blog/
   trunk/src/shotoku/org/jboss/blog/model/
   trunk/src/shotoku/org/jboss/blog/model/shotoku/
   trunk/src/shotoku/org/jboss/blog/model/shotoku/ShotokuFeed.java
   trunk/src/shotoku/org/jboss/blog/session/
   trunk/src/shotoku/org/jboss/blog/session/feed/
   trunk/src/shotoku/org/jboss/blog/session/feed/dao/
   trunk/src/shotoku/org/jboss/blog/session/feed/dao/ShotokuFeedDao.java
   trunk/src/shotoku/org/jboss/blog/session/feed/mod/
   trunk/src/shotoku/org/jboss/blog/session/feed/mod/ShotokuModBean.java
   trunk/src/shotoku/org/jboss/blog/session/feed/update/
   trunk/src/shotoku/org/jboss/blog/session/feed/update/ShotokuFeedUpdate.java
   trunk/src/shotoku/org/jboss/blog/session/shotoku/
   trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuFeedService.java
   trunk/view/manage/shotoku/
   trunk/view/manage/shotoku/shotoku_add.page.xml
   trunk/view/manage/shotoku/shotoku_add.xhtml
   trunk/view/manage/shotoku/shotoku_edit.page.xml
   trunk/view/manage/shotoku/shotoku_edit.xhtml
   trunk/view/manage/shotoku/shotoku_mod.xhtml
Modified:
   trunk/blog.iml
   trunk/build.xml
   trunk/resources/META-INF/application.xml
   trunk/resources/META-INF/persistence-design.xml
   trunk/resources/META-INF/persistence-dev.xml
   trunk/resources/META-INF/persistence-prod.xml
   trunk/resources/META-INF/security.drl
   trunk/resources/WEB-INF/urlrewrite.xml
   trunk/resources/messages_en.properties
   trunk/src/action/org/jboss/blog/session/feed/mod/RemoteFeedModBean.java
   trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java
   trunk/src/action/org/jboss/blog/session/parser/ParserServiceImpl.java
   trunk/src/model/org/jboss/blog/model/Enclosure.java
   trunk/src/test/org/jboss/blog/tools/FixHtmlExample1.java
Log:


Modified: trunk/blog.iml
===================================================================
--- trunk/blog.iml	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/blog.iml	2008-02-28 13:36:54 UTC (rev 227)
@@ -24,6 +24,7 @@
       <sourceFolder url="file://$MODULE_DIR$/src/model" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/portlet" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/services" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/shotoku" isTestSource="false" />
       <sourceFolder url="file://$MODULE_DIR$/src/test" isTestSource="true" />
       <sourceFolder url="file://$MODULE_DIR$/src/tools" isTestSource="false" />
       <excludeFolder url="file://$MODULE_DIR$/dist" />
@@ -187,6 +188,15 @@
         <SOURCES />
       </library>
     </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/lib/shotoku-base.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES />
+      </library>
+    </orderEntry>
     <orderEntryProperties />
   </component>
 </module>

Modified: trunk/build.xml
===================================================================
--- trunk/build.xml	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/build.xml	2008-02-28 13:36:54 UTC (rev 227)
@@ -16,15 +16,18 @@
     <property name="src.tools.dir" value="src/tools" />
     <property name="src.test.dir" value="src/test" />
     <property name="src.portlet.dir" value="src/portlet" />
+    <property name="src.shotoku.dir" value="src/shotoku" />
     <property name="lib.dir" value="lib" />
 
     <property name="jar.impl.name" value="${project.name}-impl.jar" />
     <property name="jar.api.name" value="${project.name}.jar" />
+    <property name="jar.shotoku.name" value="${project.name}-shotoku.jar" />
     <property name="portlet.name" value="${project.name}-portlet.war" />
 
     <property name="ear.dir" value="exploded-archives/${project.name}.ear" />
     <property name="jar.impl.dir" value="exploded-archives/${jar.impl.name}" />
     <property name="jar.api.dir" value="exploded-archives/${jar.api.name}" />
+    <property name="jar.shotoku.dir" value="exploded-archives/${jar.shotoku.name}" />
     <property name="war.dir" value="exploded-archives/${project.name}.war" />
     <property name="portlet.dir" value="exploded-archives/${portlet.name}" />
     <property name="test.dir" value="test-build" />
@@ -33,6 +36,7 @@
     <property name="deploy.lib.dir" value="${jboss.home}/server/default/lib" />
     <property name="ear.deploy.dir" value="${deploy.dir}/${project.name}.ear" />
     <property name="jar.deploy.dir" value="${ear.deploy.dir}/${jar.impl.name}" />
+    <property name="jar.shotoku.deploy.dir" value="${ear.deploy.dir}/${jar.shotoku.name}" />
     <property name="war.deploy.dir" value="${ear.deploy.dir}/${project.name}.war" />
     <property name="portlet.deploy.dir" value="${ear.deploy.dir}/${portlet.name}" />
     <property name="testng.jar" value="${basedir}/lib/testng.jar" />
@@ -59,9 +63,16 @@
         <pathelement path="${jar.api.dir}" />
     </path>
 
+    <path id="build.dep.classpath">
+        <fileset refid="lib" />
+        <pathelement path="${jar.api.dir}" />
+        <pathelement path="${jar.impl.dir}" />
+    </path>
+
     <target name="init" description="Initialize the build">
         <mkdir dir="${jar.impl.dir}" />
         <mkdir dir="${jar.api.dir}" />
+        <mkdir dir="${jar.shotoku.dir}" />
         <mkdir dir="${ear.dir}" />
         <mkdir dir="${war.dir}" />
         <mkdir dir="${portlet.dir}" />
@@ -96,6 +107,13 @@
                nowarn="on">
             <src path="${src.portlet.dir}" />
         </javac>
+        <javac classpathref="build.dep.classpath"
+               destdir="${jar.shotoku.dir}"
+               debug="${javac.debug}"
+               deprecation="${javac.deprecation}"
+               nowarn="on">
+            <src path="${src.shotoku.dir}" />
+        </javac>
     </target>
 
     <target name="jar" depends="compile"
@@ -109,6 +127,14 @@
                 <include name="seam.properties" />
             </fileset>
         </copy>
+
+        <!-- TODO: remove this marker for scanner -->
+        <copy todir="${jar.shotoku.dir}">
+            <fileset dir="${basedir}/resources">
+                <include name="seam.properties" />
+            </fileset>
+        </copy>
+
         <copy todir="${jar.impl.dir}/META-INF">
             <fileset dir="${basedir}/resources/META-INF">
                 <include name="ejb-jar.xml" />
@@ -117,6 +143,9 @@
         <copy tofile="${jar.impl.dir}/META-INF/persistence.xml"
               file="${basedir}/resources/META-INF/persistence-${profile}.xml"
               overwrite="true"/>
+
+        <!-- Shotoku -->
+        <jar jarfile="${dist.dir}/${jar.shotoku.name}" basedir="${jar.shotoku.dir}"/>
     </target>
 
     <target name="war" depends="compile"
@@ -241,6 +270,7 @@
     <target name="archive" depends="jar,war,ear"
             description="Package the archives">
         <jar jarfile="${dist.dir}/${jar.impl.name}" basedir="${jar.impl.dir}"/>
+        <jar jarfile="${dist.dir}/${jar.shotoku.name}" basedir="${jar.shotoku.dir}"/>
         <jar jarfile="${dist.dir}/${project.name}.war" basedir="${war.dir}"/>
         <jar jarfile="${dist.dir}/${portlet.name}" basedir="${portlet.dir}"/>
         <jar jarfile="${dist.dir}/${project.name}.ear">
@@ -285,6 +315,9 @@
         <copy todir="${jar.deploy.dir}">
             <fileset dir="${jar.impl.dir}"/>
         </copy>
+        <copy todir="${jar.shotoku.deploy.dir}">
+            <fileset dir="${jar.shotoku.dir}"/>
+        </copy>
         <copy todir="${war.deploy.dir}">
             <fileset dir="${war.dir}"/>
         </copy>

Modified: trunk/resources/META-INF/application.xml
===================================================================
--- trunk/resources/META-INF/application.xml	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/resources/META-INF/application.xml	2008-02-28 13:36:54 UTC (rev 227)
@@ -14,6 +14,10 @@
    <module>
       <ejb>blog-impl.jar</ejb>
    </module>
+
+    <module>
+      <ejb>blog-shotoku.jar</ejb>
+   </module>
    
    <module>
       <web>

Modified: trunk/resources/META-INF/persistence-design.xml
===================================================================
--- trunk/resources/META-INF/persistence-design.xml	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/resources/META-INF/persistence-design.xml	2008-02-28 13:36:54 UTC (rev 227)
@@ -21,6 +21,7 @@
         <class>org.jboss.blog.model.security.SecurityMapping</class>
         <class>org.jboss.blog.model.security.SecurityGroup</class>
         <class>org.jboss.blog.model.security.SecurityUser</class>
+        <class>org.jboss.blog.model.shotoku.ShotokuFeed</class>
         <properties>
             <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
             <property name="hibernate.hbm2ddl.auto" value="update"/>

Modified: trunk/resources/META-INF/persistence-dev.xml
===================================================================
--- trunk/resources/META-INF/persistence-dev.xml	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/resources/META-INF/persistence-dev.xml	2008-02-28 13:36:54 UTC (rev 227)
@@ -21,6 +21,7 @@
         <class>org.jboss.blog.model.security.SecurityMapping</class>
         <class>org.jboss.blog.model.security.SecurityGroup</class>
         <class>org.jboss.blog.model.security.SecurityUser</class>
+        <class>org.jboss.blog.model.shotoku.ShotokuFeed</class>
         <properties>
             <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
             <property name="hibernate.hbm2ddl.auto" value="update"/>

Modified: trunk/resources/META-INF/persistence-prod.xml
===================================================================
--- trunk/resources/META-INF/persistence-prod.xml	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/resources/META-INF/persistence-prod.xml	2008-02-28 13:36:54 UTC (rev 227)
@@ -21,6 +21,7 @@
         <class>org.jboss.blog.model.security.SecurityMapping</class>
         <class>org.jboss.blog.model.security.SecurityGroup</class>
         <class>org.jboss.blog.model.security.SecurityUser</class>
+        <class>org.jboss.blog.model.shotoku.ShotokuFeed</class>
         <properties>
             <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
             <property name="hibernate.hbm2ddl.auto" value="update"/>

Modified: trunk/resources/META-INF/security.drl
===================================================================
--- trunk/resources/META-INF/security.drl	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/resources/META-INF/security.drl	2008-02-28 13:36:54 UTC (rev 227)
@@ -10,6 +10,14 @@
 import org.jboss.blog.model.security.FeedsSecurityRole;
 import org.jboss.blog.session.security.FeedsCombinedRole;
 
+// TODO: remove
+rule Dev
+when
+  c: PermissionCheck()
+then
+  c.grant();
+end;
+
 rule CanDoAnything
 when
   c: PermissionCheck()

Modified: trunk/resources/WEB-INF/urlrewrite.xml
===================================================================
--- trunk/resources/WEB-INF/urlrewrite.xml	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/resources/WEB-INF/urlrewrite.xml	2008-02-28 13:36:54 UTC (rev 227)
@@ -34,7 +34,7 @@
     <!-- Feeds -->
 
     <rule>
-        <from>^/feed/([a-z0-9_]*)(\?.+)?$</from>
+        <from>^/feed/([a-z0-9_]+)(\?.+)?$</from>
         <to>/feeds.seam?name=$1</to>
     </rule>
 
@@ -46,7 +46,7 @@
     <!-- Feed view -->
 
     <rule>
-        <from>^/view/([a-z0-9_]*)(\?.+)?$</from>
+        <from>^/view/([a-z0-9_]+)(\?.+)?$</from>
         <to>/view/feed.seam?name=$1$2</to>
     </rule>
 

Modified: trunk/resources/messages_en.properties
===================================================================
--- trunk/resources/messages_en.properties	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/resources/messages_en.properties	2008-02-28 13:36:54 UTC (rev 227)
@@ -99,9 +99,12 @@
 blog.template.added=Template {0} of type {1} added.
 blog.template.new.existingname=A template with that name already exists.
 
+blog.feed.post.invalid=Post: '#0', property: #1, #2.
+blog.feed.enclosure.invalid=Enclosure on post: '#0' with url '#1', property: #2, #3
+blog.feed.image.invalid=Image for post: '#0', property: #1, #2
+
 blog.feed.remote.address.updated=Remote feed's {0} address changed.
 blog.feed.remote.postauthor.updated=Remote feed {0} updated.
-blog.feed.remote.invalid=Property: #0, #1.
 blog.feed.remote.adding.quickstart=Enter your atom/rss2 feed address in the box below; if it is correct \
   and the feed parses without any problems, you'll be able to proceed and fill in other details of the new feed.
 blog.feed.remote.mod.authors=You can choose how the author of a post is determined: the value can be either taken \

Added: trunk/src/action/org/jboss/blog/session/feed/mod/PostsValidator.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/feed/mod/PostsValidator.java	                        (rev 0)
+++ trunk/src/action/org/jboss/blog/session/feed/mod/PostsValidator.java	2008-02-28 13:36:54 UTC (rev 227)
@@ -0,0 +1,99 @@
+package org.jboss.blog.session.feed.mod;
+
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.faces.FacesMessages;
+import org.jboss.seam.core.Validators;
+import org.jboss.blog.model.Post;
+import org.jboss.blog.model.Enclosure;
+import org.jboss.blog.model.Image;
+import org.hibernate.validator.InvalidValue;
+import org.hibernate.validator.ClassValidator;
+
+import javax.faces.application.FacesMessage;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:adam at warski.org">Adam Warski</a>
+ */
+ at Scope(ScopeType.STATELESS)
+ at Name("postsValidator")
+ at AutoCreate
+public class PostsValidator {
+    @In
+    private Validators validators;
+
+    @In
+    private FacesMessages facesMessages;
+
+    public boolean validatePosts(List<Post> posts, boolean checkLinks, String controlForMessages)  {
+        ClassValidator<Post> postValidator = validators.getValidator(Post.class);
+        ClassValidator<Enclosure> enclosureValidator = validators.getValidator(Enclosure.class);
+        ClassValidator<Image> imageValidator = validators.getValidator(Image.class);
+
+        for (Post post : posts) {
+            InvalidValue[] invalidValues = postValidator.getInvalidValues(post);
+            if (invalidValues.length != 0) {
+                boolean validationFailed = false;
+
+                for (InvalidValue invalidValue : invalidValues) {
+                    if ((checkLinks || !"link".equals(invalidValue.getPropertyName())) &&
+                            (!"feed".equals(invalidValue.getPropertyName()))) {
+                        validationFailed = true;
+
+                        facesMessages.addToControlFromResourceBundle(controlForMessages, FacesMessage.SEVERITY_ERROR,
+                                "blog.feed.post.invalid", post.getTitle(),
+                                invalidValue.getPropertyName(), invalidValue.getMessage());
+                    }
+                }
+
+                return !validationFailed;
+            }
+
+            for (Enclosure enc : post.getEnclosures()) {
+                invalidValues = enclosureValidator.getInvalidValues(enc);
+
+                if (invalidValues.length != 0) {
+                    boolean validationFailed = false;
+
+                    for (InvalidValue invalidValue : invalidValues) {
+                        if (!"post".equals(invalidValue.getPropertyName())) {
+                            validationFailed = true;
+
+                            facesMessages.addToControlFromResourceBundle(controlForMessages, FacesMessage.SEVERITY_ERROR,
+                                    "blog.feed.enclosure.invalid", post.getTitle(), enc.getUrl(),
+                                    invalidValue.getPropertyName(), invalidValue.getMessage());
+                        }
+                    }
+
+                    return !validationFailed;
+                }
+            }
+
+            for (Image image : post.getImages()) {
+                invalidValues = imageValidator.getInvalidValues(image);
+
+                if (invalidValues.length != 0) {
+                    boolean validationFailed = false;
+
+                    for (InvalidValue invalidValue : invalidValues) {
+                        if (!"post".equals(invalidValue.getPropertyName())) {
+                            validationFailed = true;
+
+                            facesMessages.addToControlFromResourceBundle(controlForMessages, FacesMessage.SEVERITY_ERROR,
+                                    "blog.feed.enclosure.invalid", post.getTitle(),
+                                    invalidValue.getPropertyName(), invalidValue.getMessage());
+                        }
+                    }
+
+                    return !validationFailed;
+                }
+            }
+        }
+
+        return true;
+    }
+}

Modified: trunk/src/action/org/jboss/blog/session/feed/mod/RemoteFeedModBean.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/feed/mod/RemoteFeedModBean.java	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/src/action/org/jboss/blog/session/feed/mod/RemoteFeedModBean.java	2008-02-28 13:36:54 UTC (rev 227)
@@ -3,21 +3,17 @@
 import org.jboss.blog.model.feed.Feed;
 import org.jboss.blog.model.feed.RemoteFeed;
 import org.jboss.blog.model.feed.PostAuthorType;
-import org.jboss.blog.model.Post;
 import org.jboss.blog.session.feed.InvalidFeedTypeException;
 import org.jboss.blog.session.parser.ParserException;
 import org.jboss.blog.session.parser.ParserService;
 import org.jboss.blog.tools.StringTools;
 import org.jboss.seam.ScopeType;
 import org.jboss.seam.core.Events;
-import org.jboss.seam.core.Validators;
 import org.jboss.seam.annotations.In;
 import org.jboss.seam.annotations.Name;
 import org.jboss.seam.annotations.Scope;
 import org.jboss.seam.annotations.security.Restrict;
 import org.jboss.seam.faces.FacesMessages;
-import org.hibernate.validator.ClassValidator;
-import org.hibernate.validator.InvalidValue;
 
 import javax.faces.application.FacesMessage;
 import javax.persistence.EntityManager;
@@ -42,7 +38,7 @@
     private FacesMessages facesMessages;
 
     @In
-    private Validators validators;
+    private PostsValidator postsValidator;
 
     private RemoteFeed remoteFeed;
 
@@ -92,26 +88,14 @@
         getRemoteFeed().setAccepted(false);
     }
 
-    private void validateFeedAndPosts(Feed feed) throws ParserException {
-        ClassValidator<Post> postValidator = validators.getValidator(Post.class);
-
-        for (Post post : feed.getPosts()) {
-            InvalidValue[] invalidValues = postValidator.getInvalidValues(post);
-            if (invalidValues.length != 0) {
-                for (InvalidValue invalidValue : invalidValues) {
-                    facesMessages.addToControlFromResourceBundle("link", FacesMessage.SEVERITY_ERROR,
-                            "blog.feed.remote.invalid", invalidValue.getPropertyName(), invalidValue.getMessage());
-                }
-                
-                throw new ParserException("Posts are missing some information.");
-            }
-        }        
-    }
-
     public void parseFeed() throws InvalidFeedTypeException {
         try {
             parsedFeed = parserService.parse(getRemoteFeed().getRemoteLink());
-            validateFeedAndPosts(parsedFeed);
+
+            if (!postsValidator.validatePosts(parsedFeed.getPosts(), true, "link")) {
+               throw new ParserException("Posts are missing some information.");
+            }
+            
             setParseOk(true);
         } catch (ParserException e) {
             setParseException(e);

Modified: trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/src/action/org/jboss/blog/session/merge/MergeServiceBean.java	2008-02-28 13:36:54 UTC (rev 227)
@@ -7,7 +7,9 @@
 import org.jboss.blog.model.Image;
 import org.jboss.blog.service.FeedsService;
 import org.jboss.blog.service.PostNotFoundException;
+import org.jboss.blog.service.LinkService;
 import org.jboss.blog.tools.GeneralTools;
+import org.jboss.blog.tools.StringTools;
 import org.jboss.seam.ScopeType;
 import org.jboss.seam.core.Events;
 import org.jboss.seam.annotations.*;
@@ -32,6 +34,9 @@
     @In
     private TitleAsIdServiceBean titleAsIdService;
 
+    @In
+    private LinkService linkService;
+
     @Logger
     private Log log;
 
@@ -40,6 +45,12 @@
 
         log.debug("Saving post, feed: #0, post title: #1, post titleAsId: #2, published: #3.",
                 feed.getName(), post.getTitle(), post.getTitleAsId(), post.getPublished());
+
+        if (StringTools.isEmpty(post.getLink())) {
+            post.setLink(linkService.generatePostLink(post));
+        }
+
+        post.setContent(StringTools.fixHtml(post.getContent()));
         
         post.setFeed(feed);
         

Modified: trunk/src/action/org/jboss/blog/session/parser/ParserServiceImpl.java
===================================================================
--- trunk/src/action/org/jboss/blog/session/parser/ParserServiceImpl.java	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/src/action/org/jboss/blog/session/parser/ParserServiceImpl.java	2008-02-28 13:36:54 UTC (rev 227)
@@ -103,8 +103,6 @@
                         }
                     }
 
-                    post.setContent(StringTools.fixHtml(longestContent));
-
                     // Setting categories
                     post.setCategories(new ArrayList<Category>());
                     for (Object categoryObj : entry.getCategories()) {

Modified: trunk/src/model/org/jboss/blog/model/Enclosure.java
===================================================================
--- trunk/src/model/org/jboss/blog/model/Enclosure.java	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/src/model/org/jboss/blog/model/Enclosure.java	2008-02-28 13:36:54 UTC (rev 227)
@@ -28,9 +28,11 @@
     private String url;
 
     @Column
+    @NotNull
     private long length;
 
     @Length(max = 128)
+    @NotNull
     private String type;
 
     public Enclosure() { }

Added: trunk/src/shotoku/org/jboss/blog/model/shotoku/ShotokuFeed.java
===================================================================
--- trunk/src/shotoku/org/jboss/blog/model/shotoku/ShotokuFeed.java	                        (rev 0)
+++ trunk/src/shotoku/org/jboss/blog/model/shotoku/ShotokuFeed.java	2008-02-28 13:36:54 UTC (rev 227)
@@ -0,0 +1,51 @@
+package org.jboss.blog.model.shotoku;
+
+import org.jboss.blog.model.feed.Feed;
+import org.hibernate.validator.NotNull;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+
+import javax.persistence.Entity;
+import javax.persistence.Column;
+
+/**
+ * @author <a href="mailto:adam at warski.org">Adam Warski</a>
+ */
+ at Entity
+ at Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
+public class ShotokuFeed extends Feed {
+    @NotNull
+    @Column
+    private String cmId;
+
+    @NotNull
+    @Column
+    private String cmPath;
+
+    @Column
+    private String podcastPrefix;
+
+    public String getCmId() {
+        return cmId;
+    }
+
+    public void setCmId(String cmId) {
+        this.cmId = cmId;
+    }
+
+    public String getCmPath() {
+        return cmPath;
+    }
+
+    public void setCmPath(String cmPath) {
+        this.cmPath = cmPath;
+    }
+
+    public String getPodcastPrefix() {
+        return podcastPrefix;
+    }
+
+    public void setPodcastPrefix(String podcastPrefix) {
+        this.podcastPrefix = podcastPrefix;
+    }
+}

Added: trunk/src/shotoku/org/jboss/blog/session/feed/dao/ShotokuFeedDao.java
===================================================================
--- trunk/src/shotoku/org/jboss/blog/session/feed/dao/ShotokuFeedDao.java	                        (rev 0)
+++ trunk/src/shotoku/org/jboss/blog/session/feed/dao/ShotokuFeedDao.java	2008-02-28 13:36:54 UTC (rev 227)
@@ -0,0 +1,36 @@
+package org.jboss.blog.session.feed.dao;
+
+import org.jboss.blog.model.RestrictedPost;
+import org.jboss.blog.model.shotoku.ShotokuFeed;
+import org.jboss.blog.session.feed.posts.DatabaseFeedPosts;
+import org.jboss.blog.session.feed.type.FeedType;
+import org.jboss.blog.session.feed.update.ShotokuFeedUpdate;
+import org.jboss.blog.session.update.UpdateException;
+import org.jboss.seam.Component;
+
+import java.util.List;
+
+/**
+ * @author <a href="mailto:adam at warski.org">Adam Warski</a>
+ */
+ at FeedType(
+        name = "shotoku",
+        addPage = "/manage/shotoku/shotoku_add.xhtml",
+        editPage = "/manage/shotoku/shotoku_edit.xhtml",
+        model = ShotokuFeed.class)
+public class ShotokuFeedDao implements FeedDao {
+    private ShotokuFeed shotokuFeed;
+
+    public ShotokuFeedDao(ShotokuFeed shotokuFeed) {
+        this.shotokuFeed = shotokuFeed;
+    }
+
+    public List<? extends RestrictedPost> getPosts(int from, int to) {
+        return ((DatabaseFeedPosts) Component.getInstance("databaseFeedPosts")).getPosts(
+                shotokuFeed, from, to);
+    }
+
+    public void update() throws UpdateException {
+        ((ShotokuFeedUpdate) Component.getInstance("shotokuFeedUpdate")).update(shotokuFeed);
+    }
+}

Added: trunk/src/shotoku/org/jboss/blog/session/feed/mod/ShotokuModBean.java
===================================================================
--- trunk/src/shotoku/org/jboss/blog/session/feed/mod/ShotokuModBean.java	                        (rev 0)
+++ trunk/src/shotoku/org/jboss/blog/session/feed/mod/ShotokuModBean.java	2008-02-28 13:36:54 UTC (rev 227)
@@ -0,0 +1,121 @@
+package org.jboss.blog.session.feed.mod;
+
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.security.Restrict;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.faces.FacesMessages;
+import org.jboss.seam.core.Events;
+import org.jboss.blog.model.shotoku.ShotokuFeed;
+import org.jboss.blog.model.Post;
+import org.jboss.blog.session.feed.InvalidFeedTypeException;
+import org.jboss.blog.session.shotoku.ShotokuFeedService;
+import org.jboss.shotoku.exceptions.RepositoryException;
+
+import javax.persistence.EntityManager;
+import javax.faces.application.FacesMessage;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:adam at warski.org">Adam Warski</a>
+ */
+ at Scope(ScopeType.CONVERSATION)
+ at Name("shotokuFeedMod")
+public class ShotokuModBean {
+    @In
+    private FeedModBean feedMod;
+
+    @In
+    private EntityManager entityManager;
+
+    @In
+    private FacesMessages facesMessages;
+
+    @In
+    private PostsValidator postsValidator;
+
+    @In
+    private ShotokuFeedService shotokuFeedService;
+
+    private ShotokuFeed shotokuFeed;
+
+    private boolean podcast;
+
+    private boolean pathOk;
+    private Exception pathException;
+
+    private List<Post> posts;
+
+    public ShotokuFeed getShotokuFeed() throws InvalidFeedTypeException {
+        if (shotokuFeed == null) {
+            if (feedMod.getFeed() == null) {
+                shotokuFeed = new ShotokuFeed();
+                feedMod.initNewFeed(shotokuFeed);
+
+                shotokuFeed.setCmId("default");
+            } else {
+                if (feedMod.getFeed() instanceof ShotokuFeed) {
+                    shotokuFeed = (ShotokuFeed) feedMod.getFeed();
+                } else {
+                    throw new InvalidFeedTypeException();
+                }
+            }
+        }
+
+        return shotokuFeed;
+    }
+
+    public boolean isPathOk() {
+        return pathOk;
+    }
+
+    public void setPathOk(boolean pathOk) {
+        this.pathOk = pathOk;
+    }
+
+    public Exception getPathException() {
+        return pathException;
+    }
+
+    public void setPathException(Exception pathException) {
+        this.pathException = pathException;
+    }
+
+    public boolean isPodcast() {
+        return podcast;
+    }
+
+    public void setPodcast(boolean podcast) {
+        this.podcast = podcast;
+    }
+
+    public void checkPath() throws InvalidFeedTypeException {
+        try {
+            posts = shotokuFeedService.getPosts(getShotokuFeed());
+
+            if (!postsValidator.validatePosts(posts, false, "cmPath")) {
+                throw new RepositoryException("Some files are missing required properties.");
+            }
+
+            setPathOk(true);
+        } catch (RepositoryException e) {
+            setPathOk(false);
+            setPathException(e);
+        }
+    }
+
+    public void saveNew() throws InvalidFeedTypeException {
+        getShotokuFeed().setPosts(posts);
+    }
+
+    @Restrict("#{identity.hasPermission('feed', 'edit', feedMod.feed, feedMod.feed.group)}")
+    public void saveExisting() throws InvalidFeedTypeException {
+        entityManager.flush();
+
+        facesMessages.addFromResourceBundle(FacesMessage.SEVERITY_INFO, "blog.feed.updated",
+                getShotokuFeed().getName());
+
+        Events.instance().raiseEvent("org.jboss.blog.feed.updated", getShotokuFeed());
+    }
+}

Added: trunk/src/shotoku/org/jboss/blog/session/feed/update/ShotokuFeedUpdate.java
===================================================================
--- trunk/src/shotoku/org/jboss/blog/session/feed/update/ShotokuFeedUpdate.java	                        (rev 0)
+++ trunk/src/shotoku/org/jboss/blog/session/feed/update/ShotokuFeedUpdate.java	2008-02-28 13:36:54 UTC (rev 227)
@@ -0,0 +1,50 @@
+package org.jboss.blog.session.feed.update;
+
+import org.jboss.blog.model.shotoku.ShotokuFeed;
+import org.jboss.blog.model.Post;
+import org.jboss.blog.session.merge.MergeServiceBean;
+import org.jboss.blog.session.update.UpdateException;
+import org.jboss.blog.session.feed.lock.FeedsLocksBean;
+import org.jboss.blog.session.shotoku.ShotokuFeedService;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.shotoku.exceptions.RepositoryException;
+
+import java.util.concurrent.locks.Lock;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:adam at warski.org">Adam Warski</a>
+ */
+ at Name("shotokuFeedUpdate")
+ at Scope(ScopeType.STATELESS)
+public class ShotokuFeedUpdate {
+    @In
+    private ShotokuFeedService shotokuFeedService;
+
+    @In
+    private MergeServiceBean mergeService;
+
+    @In
+    private FeedsLocksBean feedsLocks;
+
+    public void update(ShotokuFeed feed) throws UpdateException {
+        Lock feedLock = feedsLocks.getLockForFeed(feed.getName());
+        feedLock.lock();
+        try {
+            List<Post> posts;
+
+            try {
+                posts = shotokuFeedService.getPosts(feed);
+            } catch (RepositoryException e) {
+                throw new UpdateException(e);
+            }
+
+            mergeService.merge(feed, posts);
+        } finally {
+            feedLock.unlock();
+        }
+    }
+}

Added: trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuFeedService.java
===================================================================
--- trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuFeedService.java	                        (rev 0)
+++ trunk/src/shotoku/org/jboss/blog/session/shotoku/ShotokuFeedService.java	2008-02-28 13:36:54 UTC (rev 227)
@@ -0,0 +1,78 @@
+package org.jboss.blog.session.shotoku;
+
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.ScopeType;
+import org.jboss.blog.model.Post;
+import org.jboss.blog.model.Enclosure;
+import org.jboss.blog.model.Image;
+import org.jboss.blog.model.Category;
+import org.jboss.blog.model.shotoku.ShotokuFeed;
+import org.jboss.blog.service.LinkService;
+import org.jboss.blog.tools.StringTools;
+import org.jboss.shotoku.ContentManager;
+import org.jboss.shotoku.Node;
+import org.jboss.shotoku.Directory;
+import org.jboss.shotoku.exceptions.RepositoryException;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author <a href="mailto:adam at warski.org">Adam Warski</a>
+ */
+ at Scope(ScopeType.STATELESS)
+ at Name("shotokuFeedService")
+ at AutoCreate
+public class ShotokuFeedService {
+    @In
+    private LinkService linkService;
+
+    public List<Post> getPosts(ShotokuFeed feed) throws RepositoryException {
+        ContentManager cm = ContentManager.getContentManager(feed.getCmId(), feed.getCmPath());
+
+        List<Post> posts = new ArrayList<Post>();
+
+        if (cm == null) {
+            throw new RepositoryException("Couldn't initialize the specified content manager.");
+        }
+
+        Directory rootDir = cm.getRootDirectory();
+        if (rootDir == null) {
+            throw new RepositoryException("Couldn't get the root directory in the specified content manager.");
+        }
+
+        for (Node node : cm.getRootDirectory().getNodes()) {
+            Post post = new Post();
+
+            post.setAuthor(node.getProperty("author"));
+            post.setCategories(new ArrayList<Category>());
+            post.setEnclosures(new ArrayList<Enclosure>());
+            post.setImages(new ArrayList<Image>());
+            post.setModified(node.getLastModificationDate());
+            post.setPublished(node.getCreatedDate());
+            post.setTitle(node.getProperty("title"));
+
+            if (!StringTools.isEmpty(feed.getPodcastPrefix())) {
+                post.setContent(node.getProperty("description"));
+
+                post.getEnclosures().add(new Enclosure(post,
+                        linkService.getServerAddress() + '/' + feed.getPodcastPrefix() + '/' + node.getName(),
+                        node.getLength(), node.getMimeType()));
+
+                String thumbnail = node.getProperty("thumbnail");
+                if (!StringTools.isEmpty(thumbnail)) {
+                    post.getImages().add(new Image(post, linkService.getServerAddress() + '/' + thumbnail));
+                }
+            } else {
+                post.setContent(node.getContent());
+            }
+
+            posts.add(post);
+        }
+
+        return posts;
+    }
+}

Modified: trunk/src/test/org/jboss/blog/tools/FixHtmlExample1.java
===================================================================
--- trunk/src/test/org/jboss/blog/tools/FixHtmlExample1.java	2008-02-27 15:53:21 UTC (rev 226)
+++ trunk/src/test/org/jboss/blog/tools/FixHtmlExample1.java	2008-02-28 13:36:54 UTC (rev 227)
@@ -5,12 +5,6 @@
  */
 public class FixHtmlExample1 {
     public static void main(String[] args) {
-        System.out.println(StringTools.fixHtml("<p>There are times that I realize I haven&#8217;t directed my own music choices for a while.  Maybe I&#8217;ve been traveling, spending all day on the phone, or simply driving down the road with the radio inadvertently tuned to KRAP-FM.</p>\n" +
-                "<p>And I find my motivation waning, my creativity lacking, and my general happiness in deficit.  Music matters to me.  But even then, I&#8217;ll have trouble finding the <strong>right</strong> music to listen to.  Somehow the 26.5 days of music jammed into iTunes just is not sufficient.  The online streams seem off.</p>\n" +
-                "<p>But then there are days like today, when my wife introduced me to <a href=\"http://en.wikipedia.org/wiki/Jose_Gonzales\" title=\"Wikipedia says...\">José González</a>.  This man sings exactly the right way for today.  Plus the video has a creepy pigman.</p>\n" +
-                "<p><center><br />\n" +
-                "<object height=\"355\" width=\"425\"></p>\n" +
-                "<param name=\"movie\" value=\"http://www.youtube.com/v/FFiGPMxsnB4&#38;rel=1\"></param>\n" +
-                "<param name=\"wmode\" value=\"transparent\"></param><embed src=\"http://www.youtube.com/v/FFiGPMxsnB4&#38;rel=1\" type=\"application/x-shockwave-flash\" wmode=\"transparent\" height=\"355\" width=\"425\"></embed></object></center></p>"));
+        System.out.println(StringTools.fixHtml("Gurkan Erdogdu and Kris Verlaenen a warm welcome in our <a href=\"http://jboss.com/index.html?module=bb&op=viewforum&f=201\">forums</a>!"));
     }
 }

Added: trunk/view/manage/shotoku/shotoku_add.page.xml
===================================================================
--- trunk/view/manage/shotoku/shotoku_add.page.xml	                        (rev 0)
+++ trunk/view/manage/shotoku/shotoku_add.page.xml	2008-02-28 13:36:54 UTC (rev 227)
@@ -0,0 +1,6 @@
+<page view-id="/manage/shotoku/shotoku_add.xhtml" login-required="true">
+    <begin-conversation flush-mode="manual" join="true" />
+    <navigation from-action="#{shotokuFeedMod.saveNew}">
+        <redirect view-id="/manage/feed_add.xhtml" />
+    </navigation>
+</page>

Added: trunk/view/manage/shotoku/shotoku_add.xhtml
===================================================================
--- trunk/view/manage/shotoku/shotoku_add.xhtml	                        (rev 0)
+++ trunk/view/manage/shotoku/shotoku_add.xhtml	2008-02-28 13:36:54 UTC (rev 227)
@@ -0,0 +1,20 @@
+<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"
+                xmlns:s="http://jboss.com/products/seam/taglib"
+                xmlns:ui="http://java.sun.com/jsf/facelets"
+                xmlns:f="http://java.sun.com/jsf/core"
+                xmlns:h="http://java.sun.com/jsf/html"
+                xmlns:rich="http://richfaces.org/rich"
+                xmlns:a="http://richfaces.org/a4j"
+                template="../../layout/template.xhtml">
+    <ui:define name="header">
+        Add a Shotoku feed
+    </ui:define>
+    
+    <ui:define name="body">
+        <ui:include src="shotoku_mod.xhtml">
+            <ui:param name="new" value="true" />
+        </ui:include>
+    </ui:define>
+</ui:composition>

Added: trunk/view/manage/shotoku/shotoku_edit.page.xml
===================================================================
--- trunk/view/manage/shotoku/shotoku_edit.page.xml	                        (rev 0)
+++ trunk/view/manage/shotoku/shotoku_edit.page.xml	2008-02-28 13:36:54 UTC (rev 227)
@@ -0,0 +1,9 @@
+<page view-id="/manage/shotoku/shotoku_edit.xhtml" login-required="true">
+    <begin-conversation flush-mode="manual" join="true" />
+    <param name="name" converterId="feedConverter" value="#{feedMod.feed}" />
+    <restrict>#{identity.hasPermission('feed', 'edit', feedMod.feed, feedMod.feed.group)}</restrict>
+    <navigation from-action="#{shotokuFeedMod.saveExisting}">
+        <end-conversation />
+        <redirect view-id="/manage/index.xhtml" />
+    </navigation>
+</page>
\ No newline at end of file

Added: trunk/view/manage/shotoku/shotoku_edit.xhtml
===================================================================
--- trunk/view/manage/shotoku/shotoku_edit.xhtml	                        (rev 0)
+++ trunk/view/manage/shotoku/shotoku_edit.xhtml	2008-02-28 13:36:54 UTC (rev 227)
@@ -0,0 +1,20 @@
+<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"
+                xmlns:s="http://jboss.com/products/seam/taglib"
+                xmlns:ui="http://java.sun.com/jsf/facelets"
+                xmlns:f="http://java.sun.com/jsf/core"
+                xmlns:h="http://java.sun.com/jsf/html"
+                xmlns:rich="http://richfaces.org/rich"
+                xmlns:a="http://richfaces.org/a4j"
+                template="../../layout/template.xhtml">
+    <ui:define name="header">
+        Edit shotoku feed: #{feedMod.feed.name}
+    </ui:define>
+
+    <ui:define name="body">
+        <ui:include src="shotoku_mod.xhtml">
+            <ui:param name="new" value="false" />
+        </ui:include>
+    </ui:define>
+</ui:composition>

Added: trunk/view/manage/shotoku/shotoku_mod.xhtml
===================================================================
--- trunk/view/manage/shotoku/shotoku_mod.xhtml	                        (rev 0)
+++ trunk/view/manage/shotoku/shotoku_mod.xhtml	2008-02-28 13:36:54 UTC (rev 227)
@@ -0,0 +1,134 @@
+<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<ui:composition xmlns="http://www.w3.org/1999/xhtml"
+                xmlns:s="http://jboss.com/products/seam/taglib"
+                xmlns:ui="http://java.sun.com/jsf/facelets"
+                xmlns:f="http://java.sun.com/jsf/core"
+                xmlns:h="http://java.sun.com/jsf/html"
+                xmlns:rich="http://richfaces.org/rich"
+                xmlns:a="http://richfaces.org/a4j">
+<div class="QuickstartMargin" id="QuickStart">
+    <ul>
+        <li>
+            <p>
+                You can convert files from a directory in SVN to posts using Shotoku.
+                The conversion is as follows:
+                <ul>
+                    <li>a - </li>
+                </ul>
+            </p>
+        </li>
+        <li>
+            <p>#{messages['blog.feed.remote.mod.authors']}</p>
+        </li>
+    </ul>
+</div>
+
+<div class="adminforms">
+<h:form>
+<h:panelGrid columns="2">
+    <h:outputLabel><span class="required">*</span> Content manager id:</h:outputLabel>
+    <h:panelGroup>
+        <h:inputText id="cmId" value="#{shotokuFeedMod.shotokuFeed.cmId}" required="true" size="55"
+                     maxlength="64">
+            <s:validate />
+        </h:inputText>
+        <a:outputPanel id="cmIdMessage">
+            <h:message for="cmId" styleClass="error" />
+        </a:outputPanel>
+    </h:panelGroup>
+
+    <h:outputLabel><span class="required">*</span> Path:</h:outputLabel>
+    <h:panelGroup>
+        <h:inputText id="cmPath" value="#{shotokuFeedMod.shotokuFeed.cmPath}" required="true" size="55"
+                     maxlength="64">
+            <s:validate />
+        </h:inputText>
+        <a:outputPanel id="cmPathMessage">
+            <h:message for="cmPath" styleClass="error" />
+        </a:outputPanel>
+    </h:panelGroup>
+
+    <h:outputLabel>This is a podcast:</h:outputLabel>
+    <h:panelGroup>
+        <h:selectBooleanCheckbox id="podcast" value="#{shotokuFeedMod.podcast}" required="true">
+            <a:support event="onchange" reRender="podcastPrefix,podcastPrefixRequired" ajaxSingle="true"
+                       bypassUpdates="false"/>
+            <s:validate />
+        </h:selectBooleanCheckbox>
+        <a:outputPanel id="podcastMessage">
+            <h:message for="podcast" styleClass="error" />
+        </a:outputPanel>
+    </h:panelGroup>
+
+    <h:outputLabel>
+        <s:span styleClass="required" rendered="#{shotokuFeedMod.podcast}" id="podcastPrefixRequired">*</s:span>
+        URL prefix for accessing podcast files:
+    </h:outputLabel>
+    <h:panelGroup>
+        <h:inputText id="podcastPrefix" value="#{shotokuFeedMod.shotokuFeed.podcastPrefix}"
+                     disabled="#{!shotokuFeedMod.podcast}" required="#{shotokuFeedMod.podcast}">
+            <s:validate />
+        </h:inputText>
+        <a:outputPanel id="podcastPrefixMessage">
+            <h:message for="podcastPrefix" styleClass="error" />
+        </a:outputPanel>
+    </h:panelGroup>
+
+    <h:outputLabel for="postAuthorType"><span class="required">*</span> Post author:</h:outputLabel>
+    <h:panelGroup>
+        <h:selectOneMenu id="postAuthorType" value="#{shotokuFeedMod.shotokuFeed.postAuthorType}"
+                         required="true" styleClass="selectwide">
+            <s:enumItem enumValue="BLOG_AUTHOR_IF_MISSING" label="Overwrite with blog author when post
+                            author is missing" />
+            <s:enumItem enumValue="POST_AUTHOR" label="Always use original post author" />
+            <s:enumItem enumValue="BLOG_AUTHOR" label="Always overwrite post author with blog author" />
+            <s:convertEnum />
+            <s:validate />
+        </h:selectOneMenu>
+    </h:panelGroup>
+
+    <h:panelGroup />
+    <h:panelGroup id="checkStatus">
+        <h:panelGroup rendered="#{shotokuFeedMod.pathOk}">
+            Checking the path was successfull! You can proceed.
+        </h:panelGroup>
+        <h:panelGroup rendered="#{!shotokuFeedMod.pathOk and shotokuFeedMod.pathException != null}">
+            Checking the path failed, because of the following exception:
+            #{shotokuFeedMod.pathException.message}
+        </h:panelGroup>
+    </h:panelGroup>
+</h:panelGrid>
+
+<s:div id="proceed" styleClass="formbuttons">
+    <ul>
+        <s:fragment rendered="#{!shotokuFeedMod.pathOk}">
+            <li>
+                <a:commandButton action="#{shotokuFeedMod.checkPath}" value="Check the path"
+                                 styleClass="submit"
+                                 reRender="checkStatus,proceed,cmId,cmIdMessage,cmPath,cmPathMessage,podcast,podcastMessage,podcastPrefix,podcastPrefixMessage" />
+            </li>
+        </s:fragment>
+        <s:fragment rendered="#{shotokuFeedMod.pathOk and new}">
+            <li>
+                <h:commandButton value="Next &#187;" action="#{shotokuFeedMod.saveNew}"
+                                 styleClass="submit" />
+            </li>
+        </s:fragment>
+        <s:fragment rendered="#{shotokuFeedMod.pathOk and !new}">
+            <li>
+                <h:commandButton value="Save" action="#{shotokuFeedMod.saveExisting}"
+                                 styleClass="submit" />
+            </li>
+        </s:fragment>
+        <li>
+            <s:button value="Cancel" view="/manage/index.xhtml" propagation="end" styleClass="submit" />
+        </li>
+        <li>
+            <ui:include src="../../common/ajax_status.xhtml" />
+        </li>
+    </ul>
+</s:div>
+</h:form>
+</div>
+</ui:composition>




More information about the jboss-cvs-commits mailing list