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

Christian Bauer christian at hibernate.org
Thu Dec 20 07:23:04 EST 2007


  User: cbauer  
  Date: 07/12/20 07:23:04

  Modified:    examples/wiki/src/main/org/jboss/seam/wiki/core/action    
                        Pager.java DirectoryHome.java NodeHome.java
  Added:       examples/wiki/src/main/org/jboss/seam/wiki/core/action    
                        Clipboard.java
  Log:
  JBSEAM-1743 - Clipboard for copying/moving of nodes
  
  Revision  Changes    Path
  1.2       +16 -3     jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Pager.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Pager.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Pager.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -b -r1.1 -r1.2
  --- Pager.java	9 Nov 2007 15:19:29 -0000	1.1
  +++ Pager.java	20 Dec 2007 12:23:04 -0000	1.2
  @@ -1,10 +1,21 @@
   package org.jboss.seam.wiki.core.action;
   
  -public class Pager {
  +import org.jboss.seam.annotations.Name;
  +import org.jboss.seam.annotations.Scope;
  +import org.jboss.seam.annotations.AutoCreate;
  +import org.jboss.seam.annotations.web.RequestParameter;
  +import org.jboss.seam.ScopeType;
  +
  +import java.io.Serializable;
  +
  + at Name("pager")
  + at Scope(ScopeType.PAGE)
  + at AutoCreate
  +public class Pager implements Serializable {
   
       private Long numOfRecords = 0l;
       private Integer page = 0;
  -    private Long pageSize = 10l;
  +    private Long pageSize = 15l;
   
       public Pager() {}
   
  @@ -32,7 +43,9 @@
           return pageSize;
       }
   
  +    @RequestParameter
       public void setPageSize(Long pageSize) {
  +        if (pageSize != null)
           this.pageSize = pageSize;
       }
   
  
  
  
  1.23      +177 -15   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.22
  retrieving revision 1.23
  diff -u -b -r1.22 -r1.23
  --- DirectoryHome.java	19 Dec 2007 04:29:25 -0000	1.22
  +++ DirectoryHome.java	20 Dec 2007 12:23:04 -0000	1.23
  @@ -7,22 +7,21 @@
   package org.jboss.seam.wiki.core.action;
   
   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.seam.contexts.Contexts;
  +import org.jboss.seam.international.Messages;
  +import org.jboss.seam.annotations.*;
   import org.jboss.seam.annotations.Observer;
  +import org.jboss.seam.annotations.datamodel.DataModel;
   import org.jboss.seam.annotations.web.RequestParameter;
   import org.jboss.seam.annotations.security.Restrict;
   import org.jboss.seam.security.Identity;
   import org.jboss.seam.wiki.core.feeds.FeedDAO;
  -import org.jboss.seam.wiki.core.model.WikiDirectory;
  -import org.jboss.seam.wiki.core.model.WikiDocument;
  -import org.jboss.seam.wiki.core.model.WikiMenuItem;
  -import org.jboss.seam.wiki.core.model.WikiNode;
  +import org.jboss.seam.wiki.core.model.*;
   import org.jboss.seam.wiki.util.WikiUtil;
   
   import javax.faces.application.FacesMessage;
   import static javax.faces.application.FacesMessage.SEVERITY_INFO;
  +import static javax.faces.application.FacesMessage.SEVERITY_ERROR;
   import java.util.*;
   
   @Name("directoryHome")
  @@ -35,13 +34,21 @@
       @In
       protected FeedDAO feedDAO;
   
  +    @In
  +    protected Clipboard clipboard;
  +
  +    @In
  +    protected Pager pager;
   
       /* -------------------------- Internal State ------------------------------ */
   
  -    // TODO: Move page size into preferences
  -    private Pager pager = new Pager(15l);
       private boolean hasFeed;
  -    private List<WikiNode> childNodes = new ArrayList<WikiNode>();
  +
  +    @DataModel(value = "childNodesList", scope = ScopeType.PAGE)
  +    private List<WikiNode> childNodes;
  +
  +    private Map<WikiNode, Boolean> selectedNodes = new HashMap<WikiNode,Boolean>();
  +
       private List<WikiDocument> childDocuments = new ArrayList<WikiDocument>();
       private List<WikiMenuItem> menuItems = new ArrayList<WikiMenuItem>();
       private SortedSet<WikiDirectory> alreadyUsedMenuItems = new TreeSet<WikiDirectory>();
  @@ -69,7 +76,12 @@
       public WikiDirectory afterNodeFound(WikiDirectory dir) {
           super.afterNodeFound(dir);
   
  +        // Hm, not pretty but we can't have a @Factory here or Seam
  +        // complains that subclass has duplicate factory
  +        if (!Contexts.getPageContext().isSet("childNodesList")) {
  +            getLog().debug("refreshing child nodes after node found");
           refreshChildNodes(dir);
  +        }
   
           return dir;
       }
  @@ -133,8 +145,8 @@
   
       @Override
       protected boolean prepareRemove() {
  -        if (getInstance().getParent() == null) return false; // Veto wiki root delete
  -        return true;
  +        // Wiki ROOT is special
  +        return getInstance().getParent() != null;
       }
   
       /* -------------------------- Messages ------------------------------ */
  @@ -186,8 +198,11 @@
       /* -------------------------- Internal Methods ------------------------------ */
   
       private void refreshChildNodes(WikiDirectory dir) {
  +        getLog().debug("refreshing child nodes of directory: " + dir);
           pager.setNumOfRecords(getWikiNodeDAO().findChildrenCount(dir));
  +        getLog().debug("number of children: " + pager.getNumOfRecords());
           if (pager.getNumOfRecords() > 0) {
  +            getLog().debug("loading children page from: " + pager.getNextRecord() + " size: " + pager.getPageSize());
               childNodes = getWikiNodeDAO().findChildren(dir, "createdOn", false, pager.getNextRecord(), pager.getPageSize());
           }
       }
  @@ -244,7 +259,10 @@
   
       @Observer(value = "PersistenceContext.filterReset", create = false)
       public void refreshChildNodes() {
  -        if (isManaged()) refreshChildNodes(getInstance());
  +        if (isManaged()) {
  +            getLog().debug("refreshing child nodes of the current instance");
  +            refreshChildNodes(getInstance());
  +        }
       }
   
       @RequestParameter
  @@ -262,8 +280,10 @@
   
       public List<WikiMenuItem> getMenuItems() { return menuItems; }
   
  +    public Map<WikiNode, Boolean> getSelectedNodes() { return selectedNodes; }
  +
       public WikiDirectory getSelectedChildDirectory() { return selectedChildDirectory; }
  -    public void setSelectedChildDirectory(WikiDirectory selectedChildDirectory) { this.selectedChildDirectory = (WikiDirectory)selectedChildDirectory; }
  +    public void setSelectedChildDirectory(WikiDirectory selectedChildDirectory) { this.selectedChildDirectory = selectedChildDirectory; }
   
       public SortedSet<WikiDirectory> getAvailableMenuItems() { return availableMenuItems; }
   
  @@ -316,4 +336,146 @@
           }
       }
   
  +    // TODO: Most of this clipboard stuff is based on the hope that nobody modifies anything while we have it in the clipboard...
  +
  +    public void clearClipboard() {
  +        clipboard.clear();
  +    }
  +
  +    public void copy() {
  +        for (Map.Entry<WikiNode, Boolean> entry : getSelectedNodes().entrySet()) {
  +            if (entry.getValue()) {
  +                getLog().debug("copying to clipboard: " + entry.getKey());
  +                clipboard.add(entry.getKey(), false);
  +            }
  +        }
  +        selectedNodes.clear();
  +    }
  +
  +    @Restrict("#{s:hasPermission('Node', 'edit', directoryHome.instance)}")
  +    public void cut() {
  +        for (Map.Entry<WikiNode, Boolean> entry : getSelectedNodes().entrySet()) {
  +            if (entry.getValue()) {
  +                getLog().debug("cutting to clipboard: " + entry.getKey());
  +                clipboard.add(entry.getKey(), true);
  +            }
  +        }
  +        selectedNodes.clear();
  +        refreshChildNodes();
  +    }
  +
  +    @Restrict("#{s:hasPermission('Node', 'create', directoryHome.instance)}")
  +    public void paste() {
  +
  +        // Batch the work
  +        int batchSize = 2;
  +        int i = 0;
  +        List<Long> batchIds = new ArrayList<Long>();
  +        for (WikiNode clipboardNode : clipboard.getItems()) {
  +            i++;
  +            batchIds.add(clipboardNode.getId());
  +            if (i % batchSize == 0) {
  +                List<WikiNode> nodesForPasteBatch = getWikiNodeDAO().findWikiNodes(batchIds);
  +                pasteNodes(nodesForPasteBatch);
  +                batchIds.clear();
  +            }
  +        }
  +        // Last batch
  +        if (batchIds.size() != 0) {
  +            List<WikiNode> nodesForPasteBatch = getWikiNodeDAO().findWikiNodes(batchIds);
  +            pasteNodes(nodesForPasteBatch);
  +        }
  +
  +        getLog().debug("completed executing paste, refreshing...");
  +
  +        selectedNodes.clear();
  +        clipboard.clear();
  +        refreshChildNodes();
  +    }
  +
  +    private void pasteNodes(List<WikiNode> nodes) {
  +        getLog().debug("executing paste batch");
  +        for (WikiNode n: nodes) {
  +            getLog().debug("pasting clipboard item: " + n);
  +            String pastedName = n.getName();
  +
  +            // Check unique name if we are not cutting and pasting into the same area
  +            if (!(clipboard.isCut(n.getId()) && n.getParent().getAreaNumber().equals(getInstance().getAreaNumber()))) {
  +                getLog().debug("pasting node into different area, checking wikiname");
  +
  +                if (!getWikiNodeDAO().isUniqueWikiname(getInstance().getAreaNumber(), WikiUtil.convertToWikiName(pastedName))) {
  +                    getLog().debug("wikiname is not unique, renaming");
  +                    if (pastedName.length() > 245) {
  +                        getFacesMessages().addToControlFromResourceBundleOrDefault(
  +                            "name",
  +                            SEVERITY_ERROR,
  +                            "lacewiki.msg.Clipboard.DuplicatePasteNameFailure",
  +                            "The name '{0}' was already in use in this area and is too long to be renamed, skipping paste.",
  +                            pastedName
  +                        );
  +                        continue; // Jump to next loop iteration when we can't append a number to the name
  +                    }
  +
  +                    // Now try to add "Copy 1", "Copy 2" etc. to the name until it is unique
  +                    int i = 1;
  +                    String attemptedName = pastedName + " " + Messages.instance().get("lacewiki.label.Clipboard.CopySuffix") + i;
  +                    while (!getWikiNodeDAO().isUniqueWikiname(getInstance().getAreaNumber(), WikiUtil.convertToWikiName(attemptedName))) {
  +                        attemptedName = pastedName + " " + Messages.instance().get("lacewiki.label.Clipboard.CopySuffix") + (++i);
  +                    }
  +                    pastedName = attemptedName;
  +
  +                    getFacesMessages().addToControlFromResourceBundleOrDefault(
  +                        "name",
  +                        SEVERITY_INFO,
  +                        "lacewiki.msg.Clipboard.DuplicatePasteName",
  +                        "The name '{0}' was already in use in this area, renamed item to '{1}'.",
  +                        n.getName(), pastedName
  +                    );
  +                }
  +            }
  +
  +            if (clipboard.isCut(n.getId())) {
  +                getLog().debug("cut pasting: " + n);
  +
  +                // Check if the cut item was a default file for its parent
  +                if ( ((WikiDirectory)n.getParent()).getDefaultFile() != null &&
  +                    ((WikiDirectory)n.getParent()).getDefaultFile().getId().equals(n.getId())) {
  +                    getLog().debug("cutting default file of directory: " + n.getParent());
  +                    ((WikiDirectory)n.getParent()).setDefaultFile(null);
  +                }
  +
  +                n.setName(pastedName);
  +                n.setWikiname(WikiUtil.convertToWikiName(pastedName));
  +                n.setParent(getInstance());
  +
  +                // If we cut and paste into a new area, all children must be updated as well
  +                if (!getInstance().getAreaNumber().equals(n.getAreaNumber())) {
  +                    n.setAreaNumber(getInstance().getAreaNumber());
  +
  +                    // TODO: Ugly and memory intensive, better use a database query but HQL updates are limited with joins
  +                    if (n.isInstance(WikiDocument.class)) {
  +                        List<WikiComment> comments = getWikiNodeDAO().findWikiCommentsFlat((WikiDocument)n, true);
  +                        for (WikiComment comment : comments) {
  +                            comment.setAreaNumber(n.getAreaNumber());
  +                        }
  +                    }
  +                }
  +
  +            } else {
  +                getLog().debug("copy pasting: " + n);
  +                WikiNode newNode = n.duplicate(true);
  +                newNode.setName(pastedName);
  +                newNode.setWikiname(WikiUtil.convertToWikiName(pastedName));
  +                newNode.setParent(getInstance());
  +                newNode.setAreaNumber(getInstance().getAreaNumber());
  +                newNode.setCreatedBy(getUserDAO().findUser(n.getCreatedBy().getId()));
  +                if (n.getLastModifiedBy() != null) {
  +                    newNode.setLastModifiedBy(getUserDAO().findUser(n.getLastModifiedBy().getId()));
  +                }
  +                getEntityManager().persist(newNode);
  +            }
  +        }
  +        getLog().debug("completed executing of paste batch");
  +    }
  +
   }
  
  
  
  1.31      +0 -32     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.30
  retrieving revision 1.31
  diff -u -b -r1.30 -r1.31
  --- NodeHome.java	19 Dec 2007 04:29:25 -0000	1.30
  +++ NodeHome.java	20 Dec 2007 12:23:04 -0000	1.31
  @@ -362,40 +362,8 @@
        */
       protected boolean beforeRemove() { return true; }
   
  -    /**
  -     * Called after the node has been disconnected from the old parent and reconnected to the new.
  -     * @param oldParent the previous parent directory
  -     * @param newParent the new parent directory
  -     */
  -    protected void afterNodeMoved(WikiDirectory oldParent, WikiDirectory newParent) {}
  -
       /* -------------------------- 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();
  -        Iterator pathIterator = rowkey.iterator();
  -        Long dirId = null;
  -        while (pathIterator.hasNext()) dirId = (Long)pathIterator.next();
  -        parentNode = nodeDAO.findDirectory(dirId);
  -        Directory oldParentDirectory = (Directory)getInstance().getParent();
  -
  -        // Move node to different directory
  -        if (parentNode.getId() != oldParentDirectory.getId()) {
  -
  -            // Null out default document of old parent
  -            removeAsDefaultDocument(oldParentDirectory);
  -
  -            // Attach to new parent
  -            getInstance().setParent(parentNode); // TODO: Disconnects from old parent?
  -            getInstance().setAreaNumber(parentNode.getAreaNumber());
  -
  -            afterNodeMoved(oldParentDirectory, parentNode);
  -        }
  -    }
  -    */
  -
       @Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
       public void selectOwner(Long creatorId) {
           User newCreator = userDAO.findUser(creatorId);
  
  
  
  1.1      date: 2007/12/20 12:23:04;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Clipboard.java
  
  Index: Clipboard.java
  ===================================================================
  package org.jboss.seam.wiki.core.action;
  
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.AutoCreate;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.wiki.core.model.WikiNode;
  
  import java.util.*;
  import java.io.Serializable;
  
  @Name("clipboard")
  @Scope(ScopeType.SESSION)
  @AutoCreate
  public class Clipboard implements Serializable {
  
      private Map<WikiNode, Boolean> items = new LinkedHashMap<WikiNode, Boolean>();
  
      public Set<WikiNode> getItems() {
          return items.keySet();
      }
  
      public List<WikiNode> getItemsAsList() {
          return new ArrayList<WikiNode>(getItems());
      }
  
      public void clear() {
          items.clear();
      }
  
      public void add(WikiNode node, Boolean cut) {
          items.put(node, cut);
      }
  
      public boolean isCut(Long nodeId) {
          for (WikiNode wikiNode : items.keySet()) {
              if (wikiNode.getId().equals(nodeId) && items.get(wikiNode)) return true;
          }
          return false;
      }
  
      public boolean isContainsCutFromDirectory(Long dirId) {
          for (WikiNode wikiNode : items.keySet()) {
              if (wikiNode.getParent().getId().equals(dirId)) return true;
          }
          return false;
      }
  }
  
  
  



More information about the jboss-cvs-commits mailing list