[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