[jboss-cvs] jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action ...

Christian Bauer christian at hibernate.org
Sat Aug 25 13:59:24 EDT 2007


  User: cbauer  
  Date: 07/08/25 13:59:24

  Modified:    examples/wiki/src/main/org/jboss/seam/wiki/core/action             
                        WikiIdentity.java DirectoryHome.java FileHome.java
                        PluginPreferenceEditor.java Menu.java UserHome.java
                        NodeHome.java NodeHistory.java DocumentHome.java
                        CommentHome.java
  Added:       examples/wiki/src/main/org/jboss/seam/wiki/core/action             
                        WikiRequestResolver.java Breadcrumb.java
  Removed:     examples/wiki/src/main/org/jboss/seam/wiki/core/action             
                        NodeBrowser.java
  Log:
  Major refactoring of navigation
  
  Revision  Changes    Path
  1.10      +16 -4     jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/WikiIdentity.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: WikiIdentity.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/WikiIdentity.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -b -r1.9 -r1.10
  --- WikiIdentity.java	17 Aug 2007 13:00:28 -0000	1.9
  +++ WikiIdentity.java	25 Aug 2007 17:59:24 -0000	1.10
  @@ -10,6 +10,7 @@
   import static org.jboss.seam.annotations.Install.APPLICATION;
   
   import org.jboss.seam.security.Identity;
  +import org.jboss.seam.security.AuthorizationException;
   import org.jboss.seam.annotations.*;
   import org.jboss.seam.annotations.intercept.BypassInterceptors;
   import org.jboss.seam.wiki.core.model.User;
  @@ -17,6 +18,7 @@
   import org.jboss.seam.wiki.core.dao.UserRoleAccessFactory;
   import org.jboss.seam.wiki.core.action.prefs.WikiPreferences;
   import org.jboss.seam.Component;
  +import org.jboss.seam.core.Events;
   
   /**
    * Need this until Drools fixes bugs and becomes usable/debuggable.
  @@ -26,13 +28,22 @@
   @Scope(SESSION)
   @BypassInterceptors
   @Install(precedence=APPLICATION)
  - at Startup
  + at AutoCreate
   public class WikiIdentity extends Identity {
   
       private User currentUser;
       private Integer currentAccessLevel;
       private WikiPreferences wikiPrefs;
   
  +    // We don't care if a user is logged in, just check it...
  +    public void checkRestriction(String expr) {
  +        if (!evaluateExpression(expr)) {
  +            Events.instance().raiseEvent("org.jboss.seam.notAuthorized");
  +            throw new AuthorizationException(String.format(
  +                    "Authorization check failed for expression [%s]", expr));
  +        }
  +    }
  +
       public boolean hasPermission(String name, String action, Object... args) {
   
           currentUser = (User)Component.getInstance("currentUser");
  @@ -84,7 +95,7 @@
           or the user is the creator of the parent directory
       */
       private boolean checkCreateAccess(Node directory) {
  -        if (directory.getId().equals(wikiPrefs.getMemberAreaId())) return false; // Member home dir is immutable
  +        //if (directory.getId().equals(wikiPrefs.getMemberAreaId())) return false; // Member home dir is immutable
           if (directory.getWriteAccessLevel() == UserRoleAccessFactory.GUESTROLE_ACCESSLEVEL) return true;
           int dirWriteAccessLevel = directory.getWriteAccessLevel();
           User dirCreator = directory.getCreatedBy();
  @@ -137,7 +148,7 @@
           he has, unless he is the creator
       */
       private boolean checkRaiseAccessLevel(Node node) {
  -        if (node.getId() != null && node.getId().equals(wikiPrefs.getMemberAreaId())) return false; // Member home dir is immutable
  +        //if (node.getId() != null && node.getId().equals(wikiPrefs.getMemberAreaId())) return false; // Member home dir is immutable
           int desiredWriteAccessLevel = node.getWriteAccessLevel();
           int desiredReadAccessLevel = node.getReadAccessLevel();
           User nodeCreator = node.getCreatedBy();
  @@ -187,10 +198,11 @@
       }
   
       /*
  -        Only admins can edit the main menu
  +        Admins can edit all menus, owners can edit their own.
       */
       private boolean checkEditMenu(Node node) {
           if (currentAccessLevel == UserRoleAccessFactory.ADMINROLE_ACCESSLEVEL) return true;
  +        if (node.getCreatedBy().getId().equals(currentUser.getId())) return true;
           return false;
       }
   
  
  
  
  1.14      +13 -11    jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DirectoryHome.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: DirectoryHome.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DirectoryHome.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -b -r1.13 -r1.14
  --- DirectoryHome.java	17 Aug 2007 13:00:28 -0000	1.13
  +++ DirectoryHome.java	25 Aug 2007 17:59:24 -0000	1.14
  @@ -27,24 +27,28 @@
       /* -------------------------- Context Wiring ------------------------------ */
   
   
  -    /* -------------------------- Internal State ------------------------------ */
  -
  -    private List<Document> childDocuments = new ArrayList<Document>();
  -    public List<Document> getChildDocuments() { return childDocuments; }
  +    /* -------------------------- Request Wiring ------------------------------ */
   
  -    /* -------------------------- Basic Overrides ------------------------------ */
  -
  -    @Override
  -    public void create() {
  -        super.create();
  +    @Observer("DirectoryHome.init")
  +    public String init() {
  +        String result = super.init();
  +        if (result != null) return result;
   
           // Fill the datamodel for outjection
           refreshChildNodes();
   
           // Feed checkbox
           hasFeed = getInstance().getFeed()!=null;
  +
  +        return null;
       }
   
  +    /* -------------------------- Internal State ------------------------------ */
  +
  +    private List<Document> childDocuments = new ArrayList<Document>();
  +    public List<Document> getChildDocuments() { return childDocuments; }
  +
  +
       /* -------------------------- Custom CUD ------------------------------ */
   
       @Override
  @@ -81,8 +85,6 @@
           return super.beforeUpdate();
       }
   
  -    
  -
       protected boolean prepareRemove() {
           if (getInstance().getParent() == null) return false; // Veto wiki root delete
           return true;
  
  
  
  1.7       +2 -0      jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/FileHome.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: FileHome.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/FileHome.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -b -r1.6 -r1.7
  --- FileHome.java	12 Jun 2007 17:51:00 -0000	1.6
  +++ FileHome.java	25 Aug 2007 17:59:24 -0000	1.7
  @@ -26,6 +26,8 @@
       @In
       Map<String, FileMetaMap.FileMetaInfo> fileMetaMap;
   
  +    /* -------------------------- Request Wiring ------------------------------ */
  +
       /* -------------------------- Internal State ------------------------------ */
   
       private String filename;
  
  
  
  1.5       +1 -1      jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/PluginPreferenceEditor.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: PluginPreferenceEditor.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/PluginPreferenceEditor.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -b -r1.4 -r1.5
  --- PluginPreferenceEditor.java	17 Aug 2007 13:00:28 -0000	1.4
  +++ PluginPreferenceEditor.java	25 Aug 2007 17:59:24 -0000	1.5
  @@ -117,7 +117,7 @@
               editors.add(editor);
           }
   
  -        @Observer("PreferenceEditor.flushAll")
  +        @Observer(value = "PreferenceEditor.flushAll", create = false)
           public void flushEditors() {
               for (PluginPreferenceEditor editor : editors) {
                   editor.flush();
  
  
  
  1.10      +2 -3      jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Menu.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Menu.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Menu.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -b -r1.9 -r1.10
  --- Menu.java	17 Aug 2007 13:00:28 -0000	1.9
  +++ Menu.java	25 Aug 2007 17:59:24 -0000	1.10
  @@ -25,7 +25,7 @@
    * @author Christian Bauer
    */
   @Name("menu")
  - at Scope(ScopeType.PAGE)
  + at Scope(ScopeType.CONVERSATION)
   public class Menu implements Serializable {
   
       @In
  @@ -38,7 +38,6 @@
       WikiPreferences wikiPreferences;
   
       NestedSetNodeWrapper<Node> root;
  -
       public NestedSetNodeWrapper<Node> getRoot() {
           if (root == null) {
               refreshRoot();
  @@ -46,7 +45,7 @@
           return root;
       }
   
  -    @Observer("Nodes.menuStructureModified")
  +    @Observer(value = "Nodes.menuStructureModified", create = false)
       public void refreshRoot() {
           root = nodeDAO.findMenuItems(
                   wikiRoot,
  
  
  
  1.15      +27 -42    jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserHome.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: UserHome.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserHome.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -b -r1.14 -r1.15
  --- UserHome.java	17 Aug 2007 13:00:28 -0000	1.14
  +++ UserHome.java	25 Aug 2007 17:59:24 -0000	1.15
  @@ -9,7 +9,6 @@
   import org.jboss.seam.Component;
   import org.jboss.seam.ScopeType;
   import org.jboss.seam.annotations.*;
  -import org.jboss.seam.annotations.web.RequestParameter;
   import org.jboss.seam.annotations.datamodel.DataModel;
   import org.jboss.seam.annotations.security.Restrict;
   import org.jboss.seam.contexts.Contexts;
  @@ -40,8 +39,13 @@
   @Scope(ScopeType.CONVERSATION)
   public class UserHome extends EntityHome<User> {
   
  -    @RequestParameter
  -    private Long userId;
  +    public Long getUserId() {
  +        return (Long)getId();
  +    }
  +
  +    public void setUserId(Long userId) {
  +        setId(userId);
  +    }
   
       @In
       private FacesMessages facesMessages;
  @@ -53,9 +57,6 @@
       private UserManagementPreferences userManagementPreferences;
   
       @In
  -    NodeBrowser browser;
  -
  -    @In
       private Hash hashUtil;
   
       @In(create = true)
  @@ -77,36 +78,23 @@
       // TODO: This should really use an InputStream and directly stream into the BLOB without consuming server memory
       private byte[] portraitImageData;
   
  -    @Override
  -    public Object getId() {
  -
  -        if (userId == null) {
  -            return super.getId();
  -        } else {
  -            return userId;
  -        }
  -    }
  -
  -    @Transactional
  -    public void create() {
  -        super.create();
  -
  +    public void init() {
           if (isManaged()) {
               if (!Identity.instance().hasPermission("User", "edit", getInstance()) ) {
                   throw new AuthorizationException("You don't have permission for this operation");
               }
  -            roles = getInstance().getRoles();
  -            oldUsername = getInstance().getUsername();
  +            if (roles == null) roles = getInstance().getRoles();
  +            if (oldUsername == null) oldUsername = getInstance().getUsername();
   
           } else {
               UserManagementPreferences userMgmtPrefs =
                       (UserManagementPreferences) Component.getInstance("userManagementPreferences");
               if (!userMgmtPrefs.isEnableRegistration() &&
                   !Identity.instance().hasPermission("User", "isAdmin", Component.getInstance("currentUser"))) {
  -                throw new RuntimeException("User registration has been disabled");
  +                throw new AuthorizationException("User registration is disabled");
               }
   
  -            defaultRole = (Role)Component.getInstance("newUserDefaultRole");
  +            if (defaultRole == null) defaultRole = (Role)Component.getInstance("newUserDefaultRole");
           }
       }
   
  @@ -164,8 +152,6 @@
                           "Activiate account: /confirmRegistration.seam?activationCode=" + getInstance().getActivationCode());
                       */
   
  -                    browser.exitConversation(false);
  -
                   } catch (Exception ex) {
                       facesMessages.add(FacesMessage.SEVERITY_ERROR, "Couldn't send confirmation email: " + ex.getMessage());
                       return "error";
  @@ -182,9 +168,16 @@
           if (!isUniqueUsername())
                   return null;
   
  +        User adminUser = (User)Component.getInstance("adminUser");
  +        User guestUser = (User)Component.getInstance("guestUser");
  +
  +        if ( !getInstance().getId().equals(adminUser.getId()) &&
  +             !getInstance().getId().equals(guestUser.getId()) &&
  +             roles != null && roles.size() > 0) {
           // Roles
           getInstance().setRoles(new ArrayList<Role>()); // Clear out the collection
           getInstance().getRoles().addAll(roles);
  +        }
   
           // Preferences
           if (preferenceEditor != null) {
  @@ -223,7 +216,7 @@
                   getLog().debug("updating portrait file data/type");
                   getInstance().getProfile().setImageContentType(portraitContentType);
                   getInstance().getProfile().setImage(
  -                        WikiUtil.resizeImage(portraitImageData, portraitContentType, 120)
  +                    WikiUtil.resizeImage(portraitImageData, portraitContentType, 80)
                   );
               } else {
                   facesMessages.addFromResourceBundleOrDefault(
  @@ -245,12 +238,8 @@
                   // TODO: If identity.logout() wouldn't kill my session, I could call it here...
                   // And I don't have cleartext password in all cases, so I can't relogin the user automatically
                   if (loginCredentialsModified) {
  -                    facesMessages.addFromResourceBundleOrDefault(
  -                        FacesMessage.SEVERITY_INFO,
  -                        getMessageKeyPrefix() + "reloginRequired",
  -                        "Credentials updated, please logout and authenticate yourself with the new credentials."
  -                    );
  -                    browser.exitConversation(false);
  +                    Identity.instance().logout();
  +                    return "updatedCurrentCredentials";
                   }
               }
           }
  @@ -264,11 +253,7 @@
           // All nodes created by this user are reset to be created by the admin user
           userDAO.resetNodeCreatorToAdmin(getInstance());
   
  -        String outcome = super.remove();
  -        if (outcome != null) {
  -            browser.exitConversation(false);
  -        }
  -        return outcome;
  +        return super.remove();
       }
   
       protected String getCreatedMessageKey() {
  
  
  
  1.22      +99 -112   jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHome.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: NodeHome.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHome.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -b -r1.21 -r1.22
  --- NodeHome.java	17 Aug 2007 13:00:28 -0000	1.21
  +++ NodeHome.java	25 Aug 2007 17:59:24 -0000	1.22
  @@ -17,23 +17,14 @@
   import org.jboss.seam.wiki.util.WikiUtil;
   import org.jboss.seam.wiki.preferences.PreferenceProvider;
   import org.jboss.seam.annotations.In;
  -import org.jboss.seam.annotations.Out;
  -import org.jboss.seam.annotations.Logger;
  -import org.jboss.seam.annotations.web.RequestParameter;
  +import org.jboss.seam.annotations.RaiseEvent;
   import org.jboss.seam.annotations.security.Restrict;
  -import org.jboss.seam.core.Events;
  -import org.jboss.seam.ScopeType;
   import org.jboss.seam.Component;
  -import org.jboss.seam.log.Log;
   import org.jboss.seam.contexts.Contexts;
   import org.jboss.seam.security.AuthorizationException;
   import org.jboss.seam.security.Identity;
  -import org.richfaces.component.html.HtmlTree;
  -import org.richfaces.component.TreeRowKey;
  -import org.richfaces.component.events.NodeSelectedEvent;
   
   import java.util.Date;
  -import java.util.Iterator;
   
   /**
    * Superclass for all creating and editing documents, directories, files, etc.
  @@ -42,54 +33,77 @@
    */
   public abstract class NodeHome<N extends Node> extends EntityHome<N> {
   
  -    @Logger static Log log;
  -
       /* -------------------------- Context Wiring ------------------------------ */
   
  -    @In private NodeDAO nodeDAO;
  -    @In private UserDAO userDAO;
  -    @In private User currentUser;
  +    @In
  +    private NodeDAO nodeDAO;
  +    @In
  +    private UserDAO userDAO;
  +    @In
  +    private User currentUser;
       protected NodeDAO getNodeDAO() { return nodeDAO; }
       protected UserDAO getUserDAO() { return userDAO; }
       protected User getCurrentUser() { return currentUser; }
   
  -    @Override
  -    @Out(value = "currentNode", scope = ScopeType.CONVERSATION)
  -    public N getInstance() {
  -        return super.getInstance();
  +    /* -------------------------- Request Wiring ------------------------------ */
  +
  +    private Long parentDirectoryId;
  +    public Long getParentDirectoryId() {
  +        return parentDirectoryId;
  +    }
  +    public void setParentDirectoryId(Long parentDirectoryId) {
  +        this.parentDirectoryId = parentDirectoryId;
       }
   
  -    /* -------------------------- Request Wiring ------------------------------ */
  +    private Directory parentDirectory;
  +    public Directory getParentDirectory() {
  +        return parentDirectory;
  +    }
  +    public void setParentDirectory(Directory parentDirectory) {
  +        this.parentDirectory = parentDirectory;
  +    }
   
  -    // Required 'Edit' request parameter
  -    @RequestParameter
  -    private Long nodeId;
  -
  -    // Required 'Edit' and 'Create' request parameter
  -    @RequestParameter
  -    private Long parentDirId;
  +    public void setNodeId(Long o) {
  +        super.setId(o);
  +    }
   
  -    /* -------------------------- Internal State ------------------------------ */
  +    public Long getNodeId() {
  +        return (Long)super.getId();
  +    }
   
  -    private Directory parentDirectory;
  -    public Directory getParentDirectory() { return parentDirectory; }
  -    public void setParentDirectory(Directory parentDirectory) { this.parentDirectory = parentDirectory; }
  +    public String init() {
   
  -    /* -------------------------- Basic Overrides ------------------------------ */
  +        getLog().debug("initializing node home");
   
  -    @Override
  -    protected String getPersistenceContextName() {
  -        return "restrictedEntityManager";
  +        // Load the parent instance
  +        if (!isIdDefined() && parentDirectoryId == null) {
  +            return "missingParameters";
       }
   
  -    // 'Edit' or 'Create'
  -    @Override
  -    public Object getId() {
  -        if (nodeId == null) {
  -            return super.getId();
  +        if (!isIdDefined()) {
  +            getLog().debug("no instance identifier, getting parent directory with id: " + parentDirectoryId);
  +            parentDirectory = nodeDAO.findDirectory(parentDirectoryId);
           } else {
  -            return nodeId;
  +            getLog().debug("using parent of instance: " + getInstance());
  +            parentDirectory = getInstance().getParent();
  +            if (parentDirectory != null) // Wiki Root doesn't have a parent
  +                parentDirectoryId = parentDirectory.getId();
           }
  +
  +        getLog().debug("initalized with parent directory: " + parentDirectory);
  +
  +        // Outject current node (required for polymorphic UI, e.g. access level dropdown boxes)
  +        Contexts.getPageContext().set("currentNode", getInstance());
  +
  +        return null;
  +    }
  +
  +    /* -------------------------- Basic Overrides ------------------------------ */
  +
  +
  +    @Override
  +    protected String getPersistenceContextName() {
  +        return "restrictedEntityManager";
       }
   
       // Access level filtered DAO for retrieval by identifier
  @@ -104,46 +118,28 @@
       @Override
       protected N createInstance() {
           N node = super.createInstance();
  -
  +        if (parentDirectory == null) {
  +            throw new IllegalStateException("Call the init() method before you use NodeHome");
  +        }
           // Set default permissions for new nodes - default to same access as parent directory
  -        node.setWriteAccessLevel(getParentDirectory().getWriteAccessLevel());
  -        node.setReadAccessLevel(getParentDirectory().getReadAccessLevel());
  +        node.setWriteAccessLevel(parentDirectory.getWriteAccessLevel());
  +        node.setReadAccessLevel(parentDirectory.getReadAccessLevel());
   
           return node;
       }
   
  -    @Override
  -    public void create() {
  -        super.create();
  -
  -        // Load the parent directory (needs to be called first)
  -        // The parentDirectory (and parentDirId) parameter can actually be null but this only happens
  -        // when the wiki root is edited... it can only be update()ed anyway, all the other code is null-safe.
  -        log.trace("loading parent directory: " + parentDirId);
  -        parentDirectory = nodeDAO.findDirectory(parentDirId);
  -
  -        if (parentDirectory == null)
  -                log.warn("######### THIS SHOULD NEVER BE NULL UNLESS WE EDIT THE WIKI ROOT");
  -
  -        // Permission checks
  -        if (!isManaged() && !Identity.instance().hasPermission("Node", "create", getParentDirectory()) ) {
  -            throw new AuthorizationException("You don't have permission for this operation");
  -        } else if ( isManaged() && !Identity.instance().hasPermission("Node", "edit", getInstance()) ) {
  -            throw new AuthorizationException("You don't have permission for this operation");
  -        }
  -
  -        // Outject current node
  -        Contexts.getConversationContext().set("currentNode", getInstance());
  -    }
  -
       /* -------------------------- Custom CUD ------------------------------ */
   
       @Override
  +    @RaiseEvent("PreferenceEditor.flushAll")
       public String persist() {
  +        checkPersistPermissions();
  +
           if (!preparePersist()) return null;
   
  -        // Permission checks
  -        checkNodeAccessLevelChangePermission();
  +        // Link the node with its parent directory
  +        getLog().trace("linking new node with its parent directory");
  +        parentDirectory.addChild(getInstance());
   
           // Last modified metadata
           setLastModifiedMetadata();
  @@ -151,39 +147,28 @@
           // Wiki name conversion
           setWikiName();
   
  -        // Link the node with its parent directory
  -        log.trace("linking new node with its parent directory");
  -        getParentDirectory().addChild(getInstance());
  -
           // Set created by user
  -        log.trace("setting created by user: " + getCurrentUser());
  +        getLog().trace("setting created by user: " + getCurrentUser());
           getInstance().setCreatedBy(getCurrentUser());
   
           // Set its area number (if subclass didn't already set it)
           if (getInstance().getAreaNumber() == null)
  -            getInstance().setAreaNumber(parentDirectory.getAreaNumber());
  +            getInstance().setAreaNumber(getInstance().getParent().getAreaNumber());
   
           // Validate
           if (!isValidModel()) return null;
   
           if (!beforePersist()) return null;
  -        log.trace("persisting new node");
  -        String outcome = super.persist();
   
  -        // Notify any plugin preferences editors to also flush
  -        log.trace("notifying preference editors to also flush");
  -        Events.instance().raiseEvent("PreferenceEditor.flushAll");
  -
  -        log.trace("completed persistsing of new node");
  -        return outcome;
  +        return super.persist();
       }
   
       @Override
  +    @RaiseEvent({"PreferenceEditor.flushAll", "Nodes.menuStructureModified"})
       public String update() {
  -        if (!prepareUpdate()) return null;
  +        checkUpdatePermissions();
   
  -        // Permission checks
  -        checkNodeAccessLevelChangePermission();
  +        if (!prepareUpdate()) return null;
   
           // Last modified metadata
           setLastModifiedMetadata();
  @@ -195,22 +180,19 @@
           if (!isValidModel()) return null;
   
           if (!beforeUpdate()) return null;
  -        String outcome = super.update();
  -
  -        // Notify any plugin preferences editors to also flush
  -        Events.instance().raiseEvent("PreferenceEditor.flushAll");
   
  -        Events.instance().raiseEvent("Nodes.menuStructureModified");
  -
  -        return outcome;
  +        return super.update();
       }
   
       @Override
  +    @RaiseEvent("Nodes.menuStructureModified")
       public String remove() {
  +        checkRemovePermissions();
  +
           if (!prepareRemove()) return null;
   
           // Unlink the node from its directory
  -        getParentDirectory().removeChild(getInstance());
  +        getInstance().getParent().removeChild(getInstance());
   
           if (!beforeRemove()) return null;
   
  @@ -218,15 +200,11 @@
           PreferenceProvider provider = (PreferenceProvider) Component.getInstance("preferenceProvider");
           provider.deleteInstancePreferences(getInstance());
   
  -        String outcome = super.remove();
  -
  -        Events.instance().raiseEvent("Nodes.menuStructureModified");
  -
  -        return outcome;
  +        return super.remove();
       }
   
       protected boolean isValidModel() {
  -        log.trace("validating model");
  +        getLog().trace("validating model");
           if (getParentDirectory() == null) return true; // Special case, editing the wiki root
   
           // Unique wiki name
  @@ -247,29 +225,36 @@
       /* -------------------------- Internal Methods ------------------------------ */
   
       protected void setWikiName() {
  -        log.trace("setting wiki name of new node");
  +        getLog().trace("setting wiki name of node");
           getInstance().setWikiname(WikiUtil.convertToWikiName(getInstance().getName()));
       }
   
       protected void setLastModifiedMetadata() {
  -        log.trace("setting last modified metadata");
  +        getLog().trace("setting last modified metadata");
           getInstance().setLastModifiedBy(currentUser);
           getInstance().setLastModifiedOn(new Date());
       }
   
  -    protected void checkNodeAccessLevelChangePermission() {
  -        /*
  -        log.trace("checking access level change permission");
  +    protected void checkPersistPermissions() {
  +        getLog().trace("checking persist permissions");
  +        if (!Identity.instance().hasPermission("Node", "create", getParentDirectory()) )
  +            throw new AuthorizationException("You don't have permission for this operation");
           if (!Identity.instance().hasPermission("Node", "changeAccessLevel", getInstance()))
               throw new AuthorizationException("You don't have permission for this operation");
  -            */
       }
   
  -    protected void removeAsDefaultDocument(Directory directory) {
  -        log.trace("removing node as the default document from directory: " + directory);
  -        if (directory.getDefaultDocument() != null &&
  -            directory.getDefaultDocument().getId().equals(getInstance().getId())
  -           ) directory.setDefaultDocument(null);
  +    protected void checkUpdatePermissions() {
  +        getLog().trace("checking update permissions");
  +        if (!Identity.instance().hasPermission("Node", "edit", getInstance()) )
  +            throw new AuthorizationException("You don't have permission for this operation");
  +        if (!Identity.instance().hasPermission("Node", "changeAccessLevel", getInstance()))
  +            throw new AuthorizationException("You don't have permission for this operation");
  +    }
  +
  +    protected void checkRemovePermissions() {
  +        getLog().trace("checking remove permissions");
  +        if (!Identity.instance().hasPermission("Node", "edit", getInstance()) )
  +            throw new AuthorizationException("You don't have permission for this operation");
       }
   
       /* -------------------------- Subclass Callbacks ------------------------------ */
  @@ -319,6 +304,7 @@
   
       /* -------------------------- Public Features ------------------------------ */
   
  +    /* Moving of nodes in the tree is not supported right now
       public void parentDirectorySelected(NodeSelectedEvent nodeSelectedEvent) {
           // TODO: There is really no API in RichFaces to get the selection! Already shouted at devs...
           TreeRowKey rowkey = (TreeRowKey)((HtmlTree)nodeSelectedEvent.getSource()).getRowKey();
  @@ -341,6 +327,7 @@
               afterNodeMoved(oldParentDirectory, parentDirectory);
           }
       }
  +    */
   
       @Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
       public void selectOwner(Long creatorId) {
  
  
  
  1.8       +13 -14    jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHistory.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: NodeHistory.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHistory.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -b -r1.7 -r1.8
  --- NodeHistory.java	17 Aug 2007 13:00:28 -0000	1.7
  +++ NodeHistory.java	25 Aug 2007 17:59:24 -0000	1.8
  @@ -38,14 +38,21 @@
       @DataModel
       private List<Node> historicalNodeList;
   
  -    @RequestParameter
       Long nodeId;
   
  +    public Long getNodeId() {
  +        return nodeId;
  +    }
  +
  +    public void setNodeId(Long nodeId) {
  +        this.nodeId = nodeId;
  +    }
  +
       @DataModelSelection
       @Out(required = false, scope = ScopeType.CONVERSATION)
       private Document selectedHistoricalNode;
   
  -    @In(required = false) @Out(scope = ScopeType.CONVERSATION)
  +    @In(required = false) @Out(required = false, scope = ScopeType.CONVERSATION)
       private Document currentNode;
   
       private String diffResult;
  @@ -56,23 +63,15 @@
               historicalNodeList = nodeDAO.findHistoricalNodes(currentNode);
       }
   
  -    @Create
  -    public void create() {
  +    public String init() {
  +        if (nodeId == null) return "missingParameter";
  +
           currentNode = nodeDAO.findDocument(nodeId);
           if (!Identity.instance().hasPermission("Node", "read", currentNode) ) {
               throw new AuthorizationException("You don't have permission for this operation");
           }
  -
           historicalNodeList = nodeDAO.findHistoricalNodes(currentNode);
  -
  -        if (historicalNodeList.size() == 0) {
  -            facesMessages.addFromResourceBundleOrDefault(
  -                FacesMessage.SEVERITY_INFO,
  -                "noHistory",
  -                "No stored history for this document, you are looking at the only existing revision.");
  -            NodeBrowser browser = (NodeBrowser) Component.getInstance("browser");
  -            browser.exitConversation(false);
  -        }
  +        return null;
       }
   
       public void diff() {
  
  
  
  1.19      +45 -28    jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DocumentHome.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: DocumentHome.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DocumentHome.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -b -r1.18 -r1.19
  --- DocumentHome.java	17 Aug 2007 13:00:28 -0000	1.18
  +++ DocumentHome.java	25 Aug 2007 17:59:24 -0000	1.19
  @@ -14,30 +14,29 @@
   import org.jboss.seam.wiki.core.action.prefs.DocumentEditorPreferences;
   import org.jboss.seam.Component;
   import org.jboss.seam.ScopeType;
  +import org.jboss.seam.log.Log;
   import org.jboss.seam.contexts.Contexts;
   
   @Name("documentHome")
   @Scope(ScopeType.CONVERSATION)
   public class DocumentHome extends NodeHome<Document> {
   
  -    /* -------------------------- Context Wiring ------------------------------ */
  -
  -    @In(required = false) private Node selectedHistoricalNode;
  -    @In private FeedDAO feedDAO;
  +    @Logger
  +    static Log log;
   
  -    /* -------------------------- Internal State ------------------------------ */
  -
  -    private Document historicalCopy;
  -    private boolean minorRevision;
  -    private String formContent;
  -    private boolean enabledPreview = false;
  -    private boolean pushOnSiteFeed = false;
  -
  -    /* -------------------------- Basic Overrides ------------------------------ */
  +    /* -------------------------- Context Wiring ------------------------------ */
   
  -    @Override
  -    public void create() {
  -        super.create();
  +    @In(required = false)
  +    private Node selectedHistoricalNode;
  +    @In
  +    private FeedDAO feedDAO;
  +
  +    /* -------------------------- Request Wiring ------------------------------ */
  +
  +    @Observer("DocumentHome.init")
  +    public String init() {
  +        String result = super.init();
  +        if (result != null) return result;
   
           // Rollback to historical revision?
           if (selectedHistoricalNode != null) {
  @@ -45,17 +44,31 @@
               getInstance().rollback(selectedHistoricalNode);
           }
   
  -        // Wiki text parser and plugins need this
  -        Contexts.getConversationContext().set("currentDocument", getInstance());
  -        Contexts.getConversationContext().set("currentDirectory", getParentDirectory());
  -
           // Make a copy
           historicalCopy = new Document(getInstance());
           minorRevision = (Boolean)((DocumentEditorPreferences)Component
                   .getInstance("docEditorPreferences")).getProperties().get("minorRevisionEnabled");
   
  +        // Wiki text parser and plugins need this
  +        log.debug("setting current document: " + getInstance());
  +        Contexts.getPageContext().set("currentDocument", getInstance());
  +        log.debug("setting current directory: " + getParentDirectory());
  +        Contexts.getPageContext().set("currentDirectory", getParentDirectory());
  +
  +        return null;
       }
   
  +    /* -------------------------- Internal State ------------------------------ */
  +
  +    private Document historicalCopy;
  +    private boolean minorRevision;
  +    private String formContent;
  +    private boolean enabledPreview = false;
  +    private boolean pushOnSiteFeed = false;
  +
  +    /* -------------------------- Basic Overrides ------------------------------ */
  +
  +
       /* -------------------------- Custom CUD ------------------------------ */
   
       protected boolean beforePersist() {
  @@ -102,16 +115,16 @@
               // New historical copy in conversation
               historicalCopy = new Document(getInstance());
   
  +            // Reset form
  +            setMinorRevision(
  +                (Boolean)((DocumentEditorPreferences)Component
  +                    .getInstance("docEditorPreferences")).getProperties().get("minorRevisionEnabled")
  +            );
           }
   
           return true;
       }
   
  -    protected boolean beforeRemove() {
  -        removeAsDefaultDocument(getParentDirectory());
  -        return super.beforeRemove();
  -    }
  -
       protected void afterNodeMoved(Directory oldParent, Directory newParent) {
           // Update view
           syncFormToInstance(oldParent); // Resolve existing links in old directory
  @@ -167,13 +180,17 @@
       }
   
       public void setShowPluginPrefs(boolean showPluginPrefs) {
  -        Contexts.getConversationContext().set("showPluginPreferences", showPluginPrefs);
  -
  +        Contexts.getPageContext().set("showPluginPreferences", showPluginPrefs);
       }
   
       public boolean isShowPluginPrefs() {
  -        Boolean showPluginPrefs = (Boolean)Contexts.getConversationContext().get("showPluginPreferences");
  +        Boolean showPluginPrefs = (Boolean)Contexts.getPageContext().get("showPluginPreferences");
           return showPluginPrefs != null ? showPluginPrefs : false;
       }
   
  +    public boolean isHistoricalNodesPresent() {
  +        Long numOfNodes = getNodeDAO().findNumberOfHistoricalNodes(getInstance());
  +        return numOfNodes != null && numOfNodes > 0;
  +    }
  +
   }
  
  
  
  1.8       +10 -12    jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/CommentHome.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: CommentHome.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/CommentHome.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -b -r1.7 -r1.8
  --- CommentHome.java	17 Aug 2007 13:00:28 -0000	1.7
  +++ CommentHome.java	25 Aug 2007 17:59:24 -0000	1.8
  @@ -33,10 +33,7 @@
       FacesMessages facesMessages;
   
       @In
  -    Document currentDocument;
  -
  -    @In
  -    Node currentDirectory;
  +    DocumentHome documentHome;
   
       @In
       User currentUser;
  @@ -55,7 +52,7 @@
           refreshComments();
       }
   
  -    @Observer("Preferences.commentsPreferences")
  +    @Observer(value = {"org.jboss.seam.postAuthenticate", "PreferenceComponent.refresh.commentsPreferences"}, create = false)
       @Transactional
       public void refreshComments() {
           entityManager.joinTransaction();
  @@ -66,7 +63,7 @@
           comments = entityManager
                   .createQuery("select c from Comment c where c.document is :doc" +
                                " order by c.createdOn " + (listCommentsAscending ? "asc" : "desc") )
  -                .setParameter("doc", currentDocument)
  +                .setParameter("doc", documentHome.getInstance())
                   .setHint("org.hibernate.cacheable", true)
                   .getResultList();
   
  @@ -76,19 +73,19 @@
               comment.setFromUserEmail(currentUser.getEmail());
               comment.setFromUserHomepage(
                   currentUser.getMemberHome() != null
  -                    ? ((WikiPreferences)Component.getInstance("wikiPreferences")).getBaseUrl()+WikiUtil.renderHomeURL(currentUser)
  +                    ? WikiUtil.renderHomeURL(currentUser)
                       : null);
           }
   
           // Default to title of document as subject
  -        comment.setSubject(currentDocument.getName());
  +        comment.setSubject(documentHome.getInstance().getName());
       }
   
       @Transactional
       public void persist() {
   
           entityManager.joinTransaction();
  -        currentDocument = entityManager.merge(currentDocument);
  +        Document currentDocument = entityManager.merge(documentHome.getInstance());
           comment.setDocument(currentDocument);
           currentDocument.getComments().add(comment);
   
  @@ -114,12 +111,13 @@
       @Transactional
       public void remove(Long commentId) {
           entityManager.joinTransaction();
  -        if (!Identity.instance().hasPermission("Comment", "delete", entityManager.merge(currentDocument)) ) {
  -            throw new AuthorizationException("You don't have permission for this operation");
  -        }
   
           Comment foundCommment = entityManager.find(Comment.class, commentId);
           if (foundCommment != null) {
  +            if (!Identity.instance().hasPermission("Comment", "delete", foundCommment.getDocument()) ) {
  +                throw new AuthorizationException("You don't have permission for this operation");
  +            }
  +
               entityManager.remove(foundCommment);
               facesMessages.addFromResourceBundleOrDefault(
                   FacesMessage.SEVERITY_INFO,
  
  
  
  1.1      date: 2007/08/25 17:59:24;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/WikiRequestResolver.java
  
  Index: WikiRequestResolver.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.seam.wiki.core.action;
  
  import org.jboss.seam.annotations.*;
  import org.jboss.seam.log.Log;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.Component;
  import org.jboss.seam.faces.FacesMessages;
  import org.jboss.seam.wiki.core.dao.NodeDAO;
  import org.jboss.seam.wiki.core.model.Document;
  import org.jboss.seam.wiki.core.model.Directory;
  import org.jboss.seam.wiki.core.model.Node;
  import org.jboss.seam.wiki.core.search.WikiSearch;
  import org.jboss.seam.wiki.util.WikiUtil;
  
  import javax.faces.application.FacesMessage;
  
  /**
   * Returns <tt>docDisplay</tt>, <tt>dirDisplay</tt>, or <tt>search</tt> for the resolved <tt>nodeId</tt>.
   * <p>
   * This resolver expects request parameters in the following format:
   * </p>
   * <pre>
   * http://host/         -- rewrite filter --> http://host/context/wiki.seam
   * http://host/123.html -- rewrite filter --> http://host/context/wiki.seam?nodeId=123
   * http://host/Foo      -- rewrite filter --> http://host/context/wiki.seam?areaName=Foo
   * http://host/Foo/Bar  -- rewrite filter --> http://host/context/wiki.seam?areaName=Foo&nodeName=Bar
   * </pre>
   * <p>
   * 'Foo' is a WikiName of a directory with a parentless parent (ROOT), we call this a logical area.
   * 'Bar' is a WikiName of a node in that logical area, unique within that area subtree.
   * </p>
   * <p>
   * We _never_ have URLs like <tt>http://host/Foo/Baz/Bar</tt> because 'Baz' would be a subdirectory
   * we don't need. An area name and a node name is enough, the node name is unique within
   * a subtree. We also never have <tt>http://host/Bar</tt>, a node name alone is not enough to
   * identify a node, we also need the area name.
   * </p>
   *<p>
   * If the given parameters can't be resolved, the following prodecure applies:
   * </p>
   * <ul>
   * <li> A fulltext search with the supplied area name is attempted, e.g. the request
   *      <tt>http://host/context/wiki.seam?areaName=HelpMe</tt> will result int a wiki fulltext
   *      search for the string "HelpMe"
   * </li>
   * <li>
   *      If the fulltext search did not return any results, the <tt>wikiStart</tt> node is displayed, as
   *      defined in the wiki preferences.
   * </li>
   * </ul>
   * <p>
   * Note that this resolver also sets the identifier and instance on the respetive *Home, e.g. on
   * <tt>documentHome</tt> when <tt>docDisplay</tt> is returned.
   * </p>
   *
   * @author Christian Bauer
   */
  @Name("wikiRequestResolver")
  @Scope(ScopeType.EVENT)
  @AutoCreate
  public class WikiRequestResolver {
  
      @Logger
      static Log log;
  
      @In
      protected org.jboss.seam.faces.Redirect redirect;
  
      @In
      private FacesMessages facesMessages;
  
      @In
      protected NodeDAO nodeDAO;
  
      protected Long nodeId;
      public Long getNodeId() { return nodeId; }
      public void setNodeId(Long nodeId) { this.nodeId = nodeId; }
      
      protected String areaName;
      public String getAreaName() { return areaName; }
      public void setAreaName(String areaName) { this.areaName = areaName; }
  
      protected String nodeName;
      public String getNodeName() { return nodeName; }
      public void setNodeName(String nodeName) { this.nodeName = nodeName; }
  
      protected String message;
  
      public String getMessage() { return message; }
      public void setMessage(String message) { this.message = message; }
  
      protected Document currentDocument = null;
      public Document getCurrentDocument() { return currentDocument; }
  
      protected Directory currentDirectory = null;
      public Directory getCurrentDirectory() { return currentDirectory; }
  
      @Transactional
      public String resolve() {
  
          // Queue a message if requested (for message passing across session invalidations)
          if (message != null) {
              facesMessages.addFromResourceBundle(
                  FacesMessage.SEVERITY_INFO,
                  message
              );
          }
  
          // Have we been called with a nodeId request parameter, could be document or directory
          if (nodeId != null) {
              log.debug("trying to resolve node id: " + nodeId);
  
              // Try to find a document
              currentDocument = nodeDAO.findDocument(nodeId);
  
              // Document not found, see if it is a directory
              if (currentDocument == null) {
                  currentDirectory = nodeDAO.findDirectory(nodeId);
  
                  // Try to get a default document of that directory
                  currentDocument = nodeDAO.findDefaultDocument(currentDirectory);
  
              } else {
                  // Document found, take its directory
                  currentDirectory = currentDocument.getParent();
              }
  
          // Have we been called with an areaName and nodeName request parameter
          } else if (areaName != null && nodeName != null) {
              log.debug("trying to resolve area name: " + areaName + " and node name: " + nodeName);
  
              // Try to find the area
              Directory area = nodeDAO.findArea(areaName);
              if (area != null) {
                  Node node = nodeDAO.findNodeInArea(area.getAreaNumber(), nodeName);
                  if (WikiUtil.isDirectory(node)) {
                      currentDirectory = (Directory)node;
                      currentDocument = nodeDAO.findDefaultDocument(currentDirectory);
                   } else {
                      currentDocument = (Document)node;
                      currentDirectory = currentDocument != null ? currentDocument.getParent() : area;
                  }
              }
  
          // Or have we been called just with an areaName request parameter
          } else if (areaName != null) {
              log.debug("trying to resolve area name: " + areaName);
              currentDirectory = nodeDAO.findArea(areaName);
              currentDocument = nodeDAO.findDefaultDocument(currentDirectory);
          }
  
          log.debug("resolved directory: " + currentDirectory + " and document: " + currentDocument);
  
          // Fall back, take the area name as a search query
          if (currentDirectory == null) {
              boolean foundMatches = false;
              if (areaName != null && areaName.length() > 0) {
                  log.debug("searching for unknown area name: " + areaName);
                  WikiSearch wikiSearch = (WikiSearch) Component.getInstance("wikiSearch");
                  wikiSearch.setSimpleQuery(areaName);
                  wikiSearch.search();
                  foundMatches = wikiSearch.getTotalCount() > 0;
              }
              if (foundMatches) {
                  log.debug("found search results");
                  return "search";
              } else {
                  log.debug("falling back to wiki start document");
                  // Fall back to default document
                  currentDocument = (Document)Component.getInstance("wikiStart");
                  currentDirectory = currentDocument.getParent();
              }
          }
  
          if (currentDocument != null) {
              nodeId = currentDocument.getId();
              DocumentHome documentHome = (DocumentHome)Component.getInstance("documentHome");
              documentHome.setId(nodeId);
              documentHome.setInstance(currentDocument);
              log.debug("displaying document: " + currentDocument);
              return "docDisplay";
          } else {
              nodeId = currentDirectory.getId();
              DirectoryHome directoryHome = (DirectoryHome)Component.getInstance("directoryHome");
              directoryHome.setId(nodeId);
              directoryHome.setInstance(currentDirectory);
              log.debug("displaying directory: " + currentDirectory);
              return "dirDisplay";
          }
      }
  
  }
  
  
  
  1.1      date: 2007/08/25 17:59:24;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Breadcrumb.java
  
  Index: Breadcrumb.java
  ===================================================================
  package org.jboss.seam.wiki.core.action;
  
  import org.jboss.seam.annotations.*;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.Component;
  import org.jboss.seam.security.Identity;
  import org.jboss.seam.wiki.core.model.Node;
  import org.jboss.seam.wiki.core.model.Directory;
  
  import java.io.Serializable;
  import java.util.List;
  import java.util.ArrayList;
  import java.util.Collections;
  
  @Name("breadcrumbFactory")
  @Scope(ScopeType.PAGE)
  public class Breadcrumb implements Serializable {
  
      @In
      Node currentNode;
  
      @Factory(value = "breadcrumb", autoCreate = true)
      public List<Node> unwrap() {
          // TODO: Maybe a nested set query would be more efficient?
          List<Node> currentDirectoryPath = new ArrayList<Node>();
          addDirectoryToPath(currentDirectoryPath, currentNode);
          Collections.reverse(currentDirectoryPath);
          return currentDirectoryPath;
      }
  
      protected void addDirectoryToPath(List<Node> path, Node currentNode) {
          if (Identity.instance().hasPermission("Node", "read", currentNode) &&
              !currentNode.getId().equals( ((Directory) Component.getInstance("wikiRoot")).getId() ) )
              path.add(currentNode);
          if (currentNode.getParent() != null ) {
              addDirectoryToPath(path, currentNode.getParent());
          }
      }
  
  }
  
  
  



More information about the jboss-cvs-commits mailing list