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

Christian Bauer christian at hibernate.org
Wed Mar 7 13:37:37 EST 2007


  User: cbauer  
  Date: 07/03/07 13:37:37

  Added:       examples/wiki/src/main/org/jboss/seam/wiki/core/action         
                        DirectoryHome.java FileHome.java Menu.java
                        UserSearch.java UserHome.java Authenticator.java
                        NodeHistory.java NodeBrowser.java DocumentHome.java
  Log:
  Moved to hot-redeploy WAR build structure
  
  Revision  Changes    Path
  1.1      date: 2007/03/07 18:37:37;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DirectoryHome.java
  
  Index: DirectoryHome.java
  ===================================================================
  package org.jboss.seam.wiki.core.action;
  
  import static javax.faces.application.FacesMessage.SEVERITY_ERROR;
  
  import org.jboss.seam.annotations.*;
  import org.jboss.seam.annotations.datamodel.DataModel;
  import org.jboss.seam.annotations.datamodel.DataModelSelection;
  import org.jboss.seam.framework.EntityHome;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.wiki.core.dao.NodeDAO;
  import org.jboss.seam.wiki.core.model.Directory;
  import org.jboss.seam.wiki.core.model.Node;
  import org.jboss.seam.wiki.core.model.Document;
  import org.jboss.seam.core.FacesMessages;
  import org.jboss.seam.core.Events;
  import org.jboss.seam.core.Conversation;
  
  import javax.persistence.Query;
  import java.util.List;
  import java.util.Collections;
  
  @Name("directoryHome")
  public class DirectoryHome extends EntityHome<Directory> {
  
      @RequestParameter
      Long dirId;
  
      @RequestParameter
      Long parentDirId;
  
      Directory parentDirectory;
  
      @In(required = false)
      @Out(required = false, scope = ScopeType.CONVERSATION) // Propagate it through the conversation
      Directory currentDirectory;
  
      @In
      private FacesMessages facesMessages;
  
      @In
      private NodeBrowser browser;
  
      @In
      private NodeDAO nodeDAO;
  
      @Override
      public Object getId() {
  
          if (dirId == null) {
              return super.getId();
          } else {
              return dirId;
          }
      }
  
      @Override
      @Transactional
      public void create() {
          super.create();
  
          currentDirectory = getInstance(); // Prepare for outjection
  
          getEntityManager().joinTransaction();
          if (parentDirId != null) {
              parentDirectory = getEntityManager().find(Directory.class, parentDirId);
          } else {
              parentDirectory = getInstance().getParent();
          }
  
          // Fill the datamodel for outjection
          refreshChildNodes();
      }
  
      // TODO: Typical exit method to get out of a root or nested conversation, JBSEAM-906
      public void exitConversation(Boolean endBeforeRedirect) {
          Conversation currentConversation = Conversation.instance();
          if (currentConversation.isNested()) {
              // End this nested conversation and return to last rendered view-id of parent
              currentConversation.endAndRedirect(endBeforeRedirect);
          } else {
              // End this root conversation
              currentConversation.end();
              // Return to the view-id that was captured when this conversation started
              if (endBeforeRedirect)
                  browser.redirectToLastBrowsedPage();
              else
                  browser.redirectToLastBrowsedPageWithConversation();
          }
      }
  
      @Override
      public String persist() {
  
          // Validate
          if (!isUniqueWikinameInDirectory(null) ||
              !isUniqueWikinameInArea()) return null;
  
          // Link the directory with its parent
          parentDirectory.addChild(getInstance());
  
          if (parentDirectory.getParent() != null) {
              // This is a subdirectory in an area
              getInstance().setAreaNumber(parentDirectory.getAreaNumber());
              return super.persist();
          } else {
              // This is a logical area
  
              // Satisfy NOT NULL constraint
              getInstance().setAreaNumber(Long.MAX_VALUE);
  
              // Do the persist() first, we need the identifier after this
              String outcome = super.persist();
  
              getInstance().setAreaNumber(getInstance().getId());
  
              // And flush() again...
              getEntityManager().flush();
              return outcome;
          }
      }
  
  
      @Override
      public String update() {
  
          // Validate
          if (!isUniqueWikinameInDirectory(getInstance()) ||
              !isUniqueWikinameInArea()) return null;
  
          Events.instance().raiseEvent("Nodes.menuStructureModified");
  
          return super.update();
      }
  
      @Override
      public String remove() {
  
          // Unlink the document from its parent directory
          parentDirectory.removeChild(getInstance());
  
          // Null the outjected value
          currentDirectory = null;
  
          Events.instance().raiseEvent("Nodes.menuStructureModified");
  
          return super.remove();
      }
  
      @Override
      public String getUpdatedMessage() {
          return super.getUpdatedMessage() + ": '" + getInstance().getName() + "'";
      }
  
  
      @Override
      public String getDeletedMessage() {
          return super.getDeletedMessage() + ": '" + getInstance().getName() + "'";
      }
  
      @Override
      public String getCreatedMessage() {
          return super.getCreatedMessage() + ": '" + getInstance().getName() + "'";
      }
  
      public Directory getParentDirectory() {
          return parentDirectory;
      }
  
      public void setParentDirectory(Directory parentDirectory) {
          this.parentDirectory = parentDirectory;
      }
  
      @DataModel
      List<Node> childNodes;
  
      @DataModelSelection
      Node selectedChildNode;
  
      public void moveNodeUpInList() {
          int position = getInstance().getChildren().indexOf(selectedChildNode);
          Collections.rotate(getInstance().getChildren().subList(position-1, position+1), 1);
          refreshChildNodes();
      }
  
      public void moveNodeDownInList() {
          int position = getInstance().getChildren().indexOf(selectedChildNode);
          Collections.rotate(getInstance().getChildren().subList(position, position+2), 1);
          refreshChildNodes();
      }
  
      public void selectDefaultDocument() {
          getInstance().setDefaultDocument((Document)selectedChildNode);
          refreshChildNodes();
      }
  
      private void refreshChildNodes() {
          childNodes = getInstance().getChildren();
      }
  
      public void previewMenuItems() {
          Events.instance().raiseEvent("Nodes.menuStructureModified");
      }
  
      // Validation rules for persist(), update(), and remove();
  
      @Transactional
      private boolean isUniqueWikinameInDirectory(Directory ignore) {
          getEntityManager().joinTransaction();
  
          String queryString = "select n from Node n where n.parent = :parent and n.wikiname = :wikiname";
          if (ignore != null)  queryString = queryString + " and not n = :ignore";
  
          Query q = getEntityManager().createQuery(queryString);
          if (ignore != null) q.setParameter("ignore", ignore);
  
          // Unique directory name within parent
          List existingChildren = q
                  .setParameter("parent", parentDirectory)
                  .setParameter("wikiname", getInstance().getWikiname())
                  .getResultList();
          if (existingChildren.size() >0) {
              facesMessages.addToControlFromResourceBundleOrDefault(
                  "name",
                  SEVERITY_ERROR,
                  getMessageKeyPrefix() + "duplicateName",
                  "Directory or document with that name already exists."
              );
              return false;
          }
          return true;
      }
  
      /**
       * This is used to check for duplicate directory names in area. We could allow duplicate
       * directory names from a logical/automatic linking perspective, but the database constraint
       * would require a custom trigger. If we don't allow duplicate directory names in a logical
       * area, we can apply a simple multicolumn UNIQUE constraint, that is a lot easier.
       *
       * @return boolean True if the current instances WikiName already exists in the parents area
       */
      @Transactional
      private boolean isUniqueWikinameInArea() {
          if (parentDirectory == null) return true;
          getEntityManager().joinTransaction();
          // Unique directory name within area
          Directory foundDirectory =
                  nodeDAO.findDirectoryInArea(parentDirectory.getAreaNumber(), getInstance().getWikiname());
          if (foundDirectory != null && foundDirectory != getInstance()) {
              facesMessages.addToControlFromResourceBundleOrDefault(
                  "name",
                  SEVERITY_ERROR,
                  getMessageKeyPrefix() + "duplicateNameInArea",
                  "Directory with that name already exists in this area."
              );
              return false;
          }
          return true;
      }
  
  }
  
  
  
  1.1      date: 2007/03/07 18:37:37;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/FileHome.java
  
  Index: FileHome.java
  ===================================================================
  package org.jboss.seam.wiki.core.action;
  
  import static javax.faces.application.FacesMessage.SEVERITY_ERROR;
  import javax.swing.*;
  
  import org.jboss.seam.annotations.*;
  import org.jboss.seam.framework.EntityHome;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.wiki.core.dao.NodeDAO;
  import org.jboss.seam.wiki.core.ui.FileMetaMap;
  import org.jboss.seam.wiki.core.model.Directory;
  import org.jboss.seam.wiki.core.model.Node;
  import org.jboss.seam.wiki.core.model.File;
  import org.jboss.seam.wiki.core.model.ImageMetaInfo;
  import org.jboss.seam.core.FacesMessages;
  import org.jboss.seam.core.Conversation;
  
  import java.util.Map;
  
  @Name("fileHome")
  public class FileHome extends EntityHome<File> {
  
      @RequestParameter
      private Long fileId;
  
      @RequestParameter
      private Long parentDirId;
  
      // Pages need this for rendering
      @Out(required = true, scope = ScopeType.CONVERSATION, value = "currentDirectory")
      Directory parentDirectory;
  
      @In
      private FacesMessages facesMessages;
  
      @In
      private NodeBrowser browser;
  
      @In
      private NodeDAO nodeDAO;
  
      @In
      Map<String, FileMetaMap.FileMetaInfo> fileMetaMap;
  
      private String filename;
      private String contentType;
      // TODO: This should really use an InputStream and directly stream into the BLOB without consuming server memory
      private byte[] filedata;
  
      private int imagePreviewSize = 240;
  
      @Override
      public Object getId() {
  
          if (fileId == null) {
              return super.getId();
          } else {
              return fileId;
          }
      }
  
      @Override
      @Transactional
      public void create() {
          super.create();
  
          // Load the parent directory
          getEntityManager().joinTransaction();
          parentDirectory = getEntityManager().find(Directory.class, parentDirId);
      }
  
      // TODO: Typical exit method to get out of a root or nested conversation, JBSEAM-906
      public void exitConversation(Boolean endBeforeRedirect) {
          Conversation currentConversation = Conversation.instance();
          if (currentConversation.isNested()) {
              // End this nested conversation and return to last rendered view-id of parent
              currentConversation.endAndRedirect(endBeforeRedirect);
          } else {
              // End this root conversation
              currentConversation.end();
              // Return to the view-id that was captured when this conversation started
              if (endBeforeRedirect)
                  browser.redirectToLastBrowsedPage();
              else
                  browser.redirectToLastBrowsedPageWithConversation();
          }
      }
  
      @Override
      public String persist() {
  
          // Validate
          if (!isUniqueWikinameInDirectory() ||
              !isUniqueWikinameInArea()) return null;
  
  
          // Sync file instance with form data
          syncFile();
  
          // Link the document with a directory
          parentDirectory.addChild(getInstance());
  
          // Set its area number
          getInstance().setAreaNumber(parentDirectory.getAreaNumber());
  
          return super.persist();
      }
  
  
      @Override
      public String update() {
  
          // Validate
          if (!isUniqueWikinameInDirectory() ||
              !isUniqueWikinameInArea()) return null;
  
          // Sync file instance with form data
          syncFile();
  
          return super.update();
      }
  
      @Override
      public String remove() {
  
          // Unlink the document from its directory
          getInstance().getParent().removeChild(getInstance());
  /*
          Events.instance().raiseEvent("Nodes.menuStructureModified");
  */
          return super.remove();
      }
  
      public String getFilename() { return filename; }
      public void setFilename(String filename) { this.filename = filename; }
  
      public String getContentType() { return contentType; }
      public void setContentType(String contentType) { this.contentType = contentType; }
  
      public byte[] getFiledata() { return filedata; }
      public void setFiledata(byte[] filedata) { this.filedata = filedata; }
  
      private void syncFile() {
          if (filedata != null && filedata.length >0) {
              getInstance().setFilename(filename);
              getInstance().setFilesize(filedata.length); // Don't trust the browsers headers!
              getInstance().setData(filedata);
              getInstance().setContentType(contentType);
  
              // Handle image/picture meta info
              if (fileMetaMap.get(getInstance().getContentType()).image) {
  
                  ImageMetaInfo imageMetaInfo =
                          getInstance().getImageMetaInfo() != null
                                  ? getInstance().getImageMetaInfo()
                                  : new ImageMetaInfo();
                  getInstance().setImageMetaInfo(imageMetaInfo);
  
                  ImageIcon icon = new ImageIcon(getInstance().getData());
                  int imageSizeX = icon.getImage().getWidth(null);
                  int imageSizeY = icon.getImage().getHeight(null);
                  getInstance().getImageMetaInfo().setSizeX(imageSizeX);
                  getInstance().getImageMetaInfo().setSizeY(imageSizeY);
              }
          }
      }
  
      public int getImagePreviewSize() {
          return imagePreviewSize;
      }
  
      public void zoomPreviewIn() {
          if (imagePreviewSize < 1600) imagePreviewSize = imagePreviewSize + 240;
      }
  
      public void zoomPreviewOut() {
          if (imagePreviewSize > 240) imagePreviewSize = imagePreviewSize - 240;
      }
  
      // Validation rules for persist(), update(), and remove();
  
      private boolean isUniqueWikinameInDirectory() {
          Node foundNode = nodeDAO.findNodeInDirectory(parentDirectory, getInstance().getWikiname());
          if (foundNode != null && foundNode != getInstance()) {
              facesMessages.addToControlFromResourceBundleOrDefault(
                  "name",
                  SEVERITY_ERROR,
                  getMessageKeyPrefix() + "duplicateName",
                  "This name is already used, please change it."
              );
              return false;
          }
          return true;
      }
  
      private boolean isUniqueWikinameInArea() {
          Node foundNode = nodeDAO.findNodeInArea(parentDirectory.getAreaNumber(), getInstance().getWikiname());
          if (foundNode != null && foundNode != getInstance()) {
              facesMessages.addToControlFromResourceBundleOrDefault(
                  "name",
                  SEVERITY_ERROR,
                  getMessageKeyPrefix() + "duplicateNameInArea",
                  "This name is already used in this area, please change it."
              );
              return false;
          }
          return true;
      }
  }
  
  
  
  1.1      date: 2007/03/07 18:37:37;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Menu.java
  
  Index: Menu.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.wiki.core.model.Node;
  import org.jboss.seam.wiki.core.model.Directory;
  import org.jboss.seam.wiki.core.ui.WikiUtil;
  
  import java.util.List;
  import java.util.ArrayList;
  import java.io.Serializable;
  
  @Name("menu")
  @Scope(ScopeType.CONVERSATION)
  public class Menu implements Serializable {
  
      private List<MenuItem> items;
      public List<MenuItem> getItems() {
          if (items == null) refreshMenuItems();
          return items;
      }
  
      /** 
       * This is very inefficient. There really is no better way if we want recursively have
       * all documents and directories with isMenuItem() in the main menu. Not even a direct
       * SQL query would help (multicolumn ordering would require by PK, not good). If this
       * can't be made performant with caching, we need to replace it with a simple one
       * or two level menu item search. Currently optimizing with batch fetching, future
       * implementation might use a nested set approach (we need one anyway for recursive
       * deletion of subtrees).
       */
      @Observer("Nodes.menuStructureModified")
      public void refreshMenuItems() {
          items = new ArrayList<MenuItem>();
          for(Node area : ((Directory)Component.getInstance("wikiRoot")).getChildren())
              addNodesToMenuTree(items, 0, area);
      }
  
      // Recursive
      private void addNodesToMenuTree(List<MenuItem> menuItems, int i, Node node) {
          MenuItem menuItem = new MenuItem(node, WikiUtil.renderURL(node));
          menuItem.setLevel(i);
          if (node.isMenuItem()) menuItems.add(menuItem); // Check flag in-memory
          if (node.getChildren() != null && node.getChildren().size() > 0) {
              i++;
              for (Node child : node.getChildren()) {
                  if (i > 1)
                      // Flatten the menu tree into two levels (simple display)
                      addNodesToMenuTree(menuItems, i, child);
                  else
                      addNodesToMenuTree(menuItem.getSubItems(), i, child);
              }
          }
      }
  
      public class MenuItem{
          private Node node;
          private int level;
          private List<MenuItem> subItems = new ArrayList<MenuItem>();
          private String url;
  
          public MenuItem(Node node, String url) { this.node = node; this.url = url; }
  
          public Node getNode() { return node; }
          public void setNode(Node node) { this.node = node; }
  
          public int getLevel() { return level; }
          public void setLevel(int level) { this.level = level; }
  
          public List<MenuItem> getSubItems() { return subItems; }
          public void setSubItems(List<MenuItem> subItems) { this.subItems = subItems; }
  
          public String getUrl() { return url; }
          public void setUrl(String url) { this.url = url; }
      }
  
      
  }
  
  
  
  1.1      date: 2007/03/07 18:37:37;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserSearch.java
  
  Index: UserSearch.java
  ===================================================================
  package org.jboss.seam.wiki.core.action;
  
  import org.jboss.seam.annotations.*;
  import org.jboss.seam.annotations.datamodel.DataModel;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.core.FacesMessages;
  import org.jboss.seam.core.Conversation;
  import org.jboss.seam.wiki.core.dao.UserDAO;
  import org.jboss.seam.wiki.core.action.NodeBrowser;
  import org.jboss.seam.wiki.core.model.User;
  
  import javax.faces.application.FacesMessage;
  import java.util.List;
  import java.io.Serializable;
  
  @Name("userSearch")
  @Scope(ScopeType.CONVERSATION)
  public class UserSearch implements Serializable {
  
      @In
      private UserDAO userDAO;
  
      @In
      private FacesMessages facesMessages;
  
      @In
      private NodeBrowser browser;
  
      private User exampleUser;
      private String orderByProperty;
      private boolean orderDescending;
      private String[] ignoreProperties;
      private int rowCount;
      private int maxPageSize;
      private int pageSize;
      private int page;
  
      @DataModel
      private List<User> usersList;
  
      @Create
      public void initialize() {
          pageSize = 10;
          maxPageSize = 1000;
          exampleUser = new User();
          orderByProperty = "username";
          orderDescending = false;
          ignoreProperties = new String[]{"passwordHash", "activated", "createdOn"};
      }
  
      // TODO: Typical exit method to get out of a root or nested conversation, JBSEAM-906
      public void exitConversation(Boolean endBeforeRedirect) {
          Conversation currentConversation = Conversation.instance();
          if (currentConversation.isNested()) {
              // End this nested conversation and return to last rendered view-id of parent
              currentConversation.endAndRedirect(endBeforeRedirect);
          } else {
              // End this root conversation
              currentConversation.end();
              // Return to the view-id that was captured when this conversation started
              if (endBeforeRedirect)
                  browser.redirectToLastBrowsedPage();
              else
                  browser.redirectToLastBrowsedPageWithConversation();
          }
      }
  
      public void find() {
          page = 0;
          queryRowCount();
          if (rowCount != 0) queryUsers();
      }
  
      public void nextPage() {
          page++;
          queryUsers();
      }
  
      public void previousPage() {
          page--;
          queryUsers();
      }
  
      public void firstPage() {
          page = 0;
          queryUsers();
      }
  
      public void lastPage() {
          page = (rowCount / pageSize);
          if (rowCount % pageSize == 0) page--;
          queryUsers();
      }
  
      private void queryRowCount() {
          rowCount = userDAO.getRowCountByExample(exampleUser, ignoreProperties);
          if (rowCount == 0) {
              facesMessages.addFromResourceBundleOrDefault(
                  FacesMessage.SEVERITY_INFO,
                  "noUserFound",
                  "No user with given attributes was found, please try again."
              );
          }
      }
  
      private void queryUsers() {
          usersList = userDAO.findByExample(exampleUser, orderByProperty, orderDescending, page * pageSize, pageSize, ignoreProperties);
      }
  
      public boolean isNextPageAvailable() {
          return usersList != null && rowCount > ((page * pageSize) + pageSize);
      }
  
      public boolean isPreviousPageAvailable() {
          return usersList != null && page > 0;
      }
      public int getPageSize() {
          return pageSize;
      }
  
      public void setPageSize(int pageSize) {
          this.pageSize = pageSize > maxPageSize ? maxPageSize : pageSize; // Prevent tampering
      }
  
      public int getRowCount() {
          return rowCount;
      }
  
      public User getExampleUser() {
          return exampleUser;
      }
  
      public void setExampleUser(User exampleUser) {
          this.exampleUser = exampleUser;
      }
  
      public String getOrderByProperty() {
          return orderByProperty;
      }
  
      public boolean isOrderDescending() {
          return orderDescending;
      }
  
      public void sortBy(String propertyName) {
          orderByProperty = propertyName;
          orderDescending = !isOrderDescending(); // Switch between ASC and DESC
          page = 0; // Reset to first page
          queryUsers();
      }
  
  }
  
  
  
  1.1      date: 2007/03/07 18:37:37;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/UserHome.java
  
  Index: UserHome.java
  ===================================================================
  package org.jboss.seam.wiki.core.action;
  
  
  import org.jboss.seam.annotations.*;
  import org.jboss.seam.core.FacesMessages;
  import org.jboss.seam.core.Renderer;
  import org.jboss.seam.core.Conversation;
  import org.jboss.seam.framework.EntityHome;
  import org.jboss.seam.wiki.core.dao.UserDAO;
  import org.jboss.seam.wiki.core.model.*;
  import org.jboss.seam.wiki.util.Hash;
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  
  import javax.faces.application.FacesMessage;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  @Name("userHome")
  public class UserHome extends EntityHome<User> {
  
      @RequestParameter
      private Long userId;
  
      @In
      private FacesMessages facesMessages;
  
      @In
      private UserDAO userDAO;
  
      @In
      private NodeBrowser browser;
  
      @In
      private Hash hashUtil;
  
      @In
      private GlobalPreferences globalPrefs;
  
      @In(required = false)
      @Out(required = false, scope = ScopeType.SESSION)
      private User authenticatedUser;
  
      @In
      private Renderer renderer;
  
      private org.jboss.seam.wiki.core.model.Role defaultRole;
  
      private String oldUsername;
      private String password;
      private String passwordControl;
  
      @Override
      public Object getId() {
  
          if (userId == null) {
              return super.getId();
          } else {
              return userId;
          }
      }
  
      @Transactional
      public void create() {
          super.create();
  
          defaultRole = userDAO.findRole(globalPrefs.getNewUserInRole());
          if (defaultRole == null) throw new RuntimeException("Default role for new users not configured");
  
          oldUsername = getInstance().getUsername();
      }
  
      // TODO: Typical exit method to get out of a root or nested conversation, JBSEAM-906
      public void exitConversation(Boolean endBeforeRedirect) {
          Conversation currentConversation = Conversation.instance();
          if (currentConversation.isNested()) {
              // End this nested conversation and return to last rendered view-id of parent
              currentConversation.endAndRedirect(endBeforeRedirect);
          } else {
              // End this root conversation
              currentConversation.end();
              // Return to the view-id that was captured when this conversation started
              if (endBeforeRedirect)
                  browser.redirectToLastBrowsedPage();
              else
                  browser.redirectToLastBrowsedPageWithConversation();
          }
      }
  
      public String persist() {
  
          // Validate
          if (!isUniqueUsername() ||
              !passwordAndControlNotNull() ||
              !passwordMatchesRegex() ||
              !passwordMatchesControl()) {
  
              // Force re-entry
              setPassword(null);
              setPasswordControl(null);
  
              return null;
          }
  
          // Assign default role
          getInstance().addRole(defaultRole);
  
          // Set password hash
          getInstance().setPasswordHash(hashUtil.hash(getPassword()));
  
          // Set activation code (unique user in time)
          String seed = getInstance().getUsername() + System.currentTimeMillis() + globalPrefs.getActivationCodeSalt();
          getInstance().setActivationCode( ((Hash)Component.getInstance("hashUtil")).hash(seed) );
  
          String outcome = super.persist();
          if (outcome != null) {
  
              try {
                  // Send confirmation email
                  renderer.render("/themes/" + globalPrefs.getThemeName() + "/mailtemplates/confirmationRegistration.xhtml");
  
                  // Redirect to last viewed page with message
                  facesMessages.addFromResourceBundleOrDefault(
                      FacesMessage.SEVERITY_INFO,
                      getMessageKeyPrefix() + "confirmationEmailSent",
                      "A confirmation e-mail has been sent to '" + getInstance().getEmail() + "'. " +
                      "Please read this e-mail to activate your account.");
  
                  exitConversation(false);
  
              } catch (Exception ex) {
                  facesMessages.add(FacesMessage.SEVERITY_ERROR, "Couldn't send confirmation email: " + ex.getMessage());
                  return "error";
              }
          }
  
          return outcome;
      }
  
  
      public String update() {
  
          // Validate
          if (!isUniqueUsername())
                  return null;
  
          boolean loginCredentialsModified = false;
  
          // User wants to change his password
          if (getPassword() != null && getPassword().length() != 0) {
              if (!passwordAndControlNotNull() ||
                  !passwordMatchesRegex() ||
                  !passwordMatchesControl()) {
  
                  // Force re-entry
                  setPassword(null);
                  setPasswordControl(null);
  
                  return null;
              } else {
                  // Set password hash
                  getInstance().setPasswordHash(hashUtil.hash(getPassword()));
                  loginCredentialsModified = true;
              }
          }
  
          // User changed his username
          if (!getInstance().getUsername().equals(oldUsername)) loginCredentialsModified = true;
  
          String outcome = super.update();
          if (outcome != null) {
  
              if (authenticatedUser != null && getInstance().getId().equals(authenticatedUser.getId())) {
                  // Updated profile of currently logged-in user
                  authenticatedUser = getInstance();
  
                  // 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."
                      );
                  }
              }
              exitConversation(false);
          }
  
          return outcome;
      }
  
      public String remove() {
  
          // Remove all role assignments
          getInstance().getRoles().clear();
  
          return super.remove();
      }
  
      protected String getCreatedMessageKey() {
          return getMessageKeyPrefix() + "registrationComplete";
      }
  
      public String getCreatedMessage() {
          return "Your account '" + getInstance().getUsername() + "' has been created.";
      }
  
      protected String getUpdatedMessageKey() {
          return getMessageKeyPrefix() + "profileUpdated";
      }
  
      public String getUpdatedMessage() {
          return "The profile '" + getInstance().getUsername() + "' has been updated.";
      }
  
      public String getPassword() { return password; }
      public void setPassword(String password) { this.password = password; }
  
      public String getPasswordControl() { return passwordControl; }
      public void setPasswordControl(String passwordControl) { this.passwordControl = passwordControl; }
  
  
      // Validation rules for persist(), update(), and remove();
  
      private boolean passwordAndControlNotNull() {
          if (getPassword() == null || getPassword().length() == 0 ||
              getPasswordControl() == null || getPasswordControl().length() == 0) {
              facesMessages.addToControlFromResourceBundleOrDefault(
                  "password",
                  FacesMessage.SEVERITY_ERROR,
                  getMessageKeyPrefix() + "passwordOrPasswordControlEmpty",
                  "Please enter your password twice."
              );
              return false;
          }
          return true;
      }
  
  
      private boolean passwordMatchesRegex() {
          Matcher matcher = Pattern.compile(globalPrefs.getPasswordRegex()).matcher(getPassword());
          if (!matcher.find()) {
              facesMessages.addToControlFromResourceBundleOrDefault(
                  "password",
                  FacesMessage.SEVERITY_ERROR,
                  getMessageKeyPrefix() + "passwordNoRegexMatch",
                  "Password does not match the pattern: " + globalPrefs.getPasswordRegex()
              );
              return false;
          }
          return true;
      }
  
      private boolean passwordMatchesControl() {
          if (!password.equals(passwordControl) ) {
              facesMessages.addToControlFromResourceBundleOrDefault(
                  "password",
                  FacesMessage.SEVERITY_ERROR,
                  getMessageKeyPrefix() + "passwordControlNoMatch",
                  "The passwords don't match."
              );
              return false;
          }
          return true;
      }
  
      @Transactional
      private boolean isUniqueUsername() {
          getEntityManager().joinTransaction();
          User foundUser = userDAO.findUser(getInstance().getUsername(), false);
          if ( foundUser != null && foundUser != getInstance()) {
              facesMessages.addToControlFromResourceBundleOrDefault(
                  "username",
                  FacesMessage.SEVERITY_ERROR,
                  getMessageKeyPrefix() + "usernameExists",
                  "A user with that name already exists."
              );
              return false;
          }
          return true;
      }
  
  }
  
  
  
  1.1      date: 2007/03/07 18:37:37;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/Authenticator.java
  
  Index: Authenticator.java
  ===================================================================
  package org.jboss.seam.wiki.core.action;
  
  import org.jboss.seam.annotations.*;
  import org.jboss.seam.wiki.core.dao.UserDAO;
  import org.jboss.seam.wiki.core.model.*;
  import org.jboss.seam.wiki.util.Hash;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.security.Identity;
  
  @Name("authenticator")
  public class Authenticator {
  
      @In
      private UserDAO userDAO;
  
      @In
      private Hash hashUtil;
  
      @Out(required = false, scope = ScopeType.SESSION)
      private User authenticatedUser;
  
      @In
      private Identity identity;
  
      @RequestParameter
      private String activationCode;
  
      @Transactional
      public boolean authenticate() {
          User user = userDAO.findUser(identity.getUsername(), true);
          if (user == null ||
              identity.getPassword() == null ||
              !user.getPasswordHash().equalsIgnoreCase(hashUtil.hash(identity.getPassword())))
              return false;
  
          authenticatedUser = user;
          for (org.jboss.seam.wiki.core.model.Role role : user.getRoles()) identity.addRole(role.getName());
  
          return true;
      }
  
      @Transactional
      public String activate() {
          User user = userDAO.findUserWithActivationCode(activationCode);
          if (user != null) {
              user.setActivated(true);
              user.setActivationCode(null);
              return "activated";
          } else {
              return "notFound";
          }
      }
  
  }
  
  
  
  1.1      date: 2007/03/07 18:37:37;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeHistory.java
  
  Index: NodeHistory.java
  ===================================================================
  package org.jboss.seam.wiki.core.action;
  
  import org.jboss.seam.annotations.*;
  import org.jboss.seam.annotations.datamodel.DataModel;
  import org.jboss.seam.annotations.datamodel.DataModelSelection;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.core.FacesMessages;
  import org.jboss.seam.core.Conversation;
  import org.jboss.seam.wiki.core.dao.NodeDAO;
  import org.jboss.seam.wiki.core.model.Node;
  import org.jboss.seam.wiki.core.model.Document;
  import org.jboss.seam.wiki.core.model.Directory;
  import org.jboss.seam.wiki.util.Diff;
  
  import javax.faces.application.FacesMessage;
  import java.io.Serializable;
  import java.util.List;
  
  @Name("nodeHistory")
  @Scope(ScopeType.CONVERSATION)
  @AutoCreate
  public class NodeHistory implements Serializable {
  
      @In
      private NodeBrowser browser;
  
      @In
      NodeDAO nodeDAO;
  
      @In
      private FacesMessages facesMessages;
  
      @DataModel
      private List<Node> historicalNodeList;
  
      @DataModelSelection
      @Out(required = false, scope = ScopeType.CONVERSATION)
      private Node selectedHistoricalNode;
  
      @In @Out(scope = ScopeType.CONVERSATION)
      private Node currentNode;
  
      @Out(scope = ScopeType.CONVERSATION)
      private Directory currentDirectory;
  
      private String diffResult;
  
      @Factory("historicalNodeList")
      public void initialize() {
          historicalNodeList = nodeDAO.findHistoricalNodes(currentNode);
          currentDirectory = (Directory)currentNode.getParent();
      }
  
      // TODO: Typical exit method to get out of a root or nested conversation, JBSEAM-906
      public void exitConversation(Boolean endBeforeRedirect) {
          Conversation currentConversation = Conversation.instance();
          if (currentConversation.isNested()) {
              // End this nested conversation and return to last rendered view-id of parent
              currentConversation.endAndRedirect(endBeforeRedirect);
          } else {
              // End this root conversation
              currentConversation.end();
              // Return to the view-id that was captured when this conversation started
              if (endBeforeRedirect)
                  browser.redirectToLastBrowsedPage();
              else
                  browser.redirectToLastBrowsedPageWithConversation();
          }
      }
  
      public void diff() {
          System.out.println("#### GENERATING NEW DIFF");
  
          String revision = ((Document)currentNode).getContent();
          String original = ((Document)selectedHistoricalNode).getContent();
  
          Diff diff = new Diff() {
              protected String getDeletionStartMarker() {
                  return "xXx";
              }
  
              protected String getDeletionEndMarker() {
                  return "XxX";
              }
  
              protected String getAdditionStartMarker() {
                  return "aAa";
              }
  
              protected String getAdditionEndMarker() {
                  return "AaA";
              }
          };
  
          String[] x = original.split("\r\n");
          String[] y = revision.split("\r\n");
  
          String[] result = diff.renderDiff(x, y, "\r\n", "\r", "\n");
          
          diffResult = Diff.renderWithDelimiter(result, "\r\n");
  
          System.out.println("############### RESULT OF THE DIFF: ######################");
  
          System.out.println(diffResult);
  
          System.out.println("#####################################");
      }
  
      public String rollback() {
          facesMessages.addFromResourceBundleOrDefault(
              FacesMessage.SEVERITY_INFO,
              "rollingBackDocument",
              "Rolling back to revision '" + selectedHistoricalNode.getRevision() + "'");
          return "rollback";
      }
  
      public String getDiffResult() {
          return diffResult;
      }
  }
  
  
  
  1.1      date: 2007/03/07 18:37:37;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/NodeBrowser.java
  
  Index: NodeBrowser.java
  ===================================================================
  package org.jboss.seam.wiki.core.action;
  
  import org.jboss.seam.annotations.*;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.wiki.core.dao.NodeDAO;
  import org.jboss.seam.wiki.core.model.Node;
  import org.jboss.seam.wiki.core.model.Directory;
  import org.jboss.seam.wiki.core.model.Document;
  import org.jboss.seam.wiki.core.ui.WikiUtil;
  
  import java.util.*;
  
  /**
   * Resolves <tt>currentDocument</tt> and <tt>currentDirectory</tt> objects for given request parameters.
   * <p>
   * URLs typically mapped and resolved with these classes:
   * <p>
   * <pre>
   * http://host/         -- rewrite filter --> http://host/context/display.seam
   * http://host/123.html -- rewrite filter --> http://host/context/display.seam?nodeId=123
   * http://host/Foo      -- rewrite filter --> http://host/context/display.seam?areaName=Foo
   * http://host/Foo/Bar  -- rewrite filter --> http://host/context/display.seam?areaName=Foo&nodeName=Bar
   * </pre>
   * '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>
   * 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.
   *
   * @author Christian Bauer
   */
  @Name("browser")
  @Scope(ScopeType.EVENT)
  @AutoCreate
  public class NodeBrowser {
  
      @RequestParameter
      protected String areaName;
  
      @RequestParameter
      protected String nodeName;
  
      protected Long nodeId;
      public Long getNodeId() { return nodeId; }
      public void setNodeId(Long nodeId) { this.nodeId = nodeId; }
  
      @In
      protected org.jboss.seam.core.Redirect redirect;
  
      @In
      protected Directory wikiRoot;
  
      @In
      protected NodeDAO nodeDAO;
  
      // These are only EVENT scoped, we don't want them to jump from DocumentBrowser to
      // DirectoryBrowser over redirects
      @In(required=false) @Out(scope = ScopeType.EVENT, required = false)
      protected Document currentDocument;
  
      @In(required=false) @Out(scope = ScopeType.EVENT, required = false)
      protected Directory currentDirectory;
  
      @Out(scope = ScopeType.EVENT)
      protected  List<Node> currentDirectoryPath = new ArrayList<Node>();
  
  
      /**
       * Executes a redirect to the last view-id that was prepare()ed.
       * <p>
       * Usually called after ending a conversation. Assumes that the caller of the method does not want to propagate
       * the current (ended) conversation across that redirect. Also removes any stored <tt>actionOutcome</tt>,
       * <tt>actionMethod</tt> or <tt>cid</tt> request parameter before redirecting, we don't want to redirect to
       * a prepare()ed page that was in a long-running conversation (temporary doesn't matter) or that was last
       * called with an action (that action would probably send us straight back into the conversation we are trying
       * to redirect out of).
       *
       * TODO: These methods and the whole navigation strategy can be simplified with http://jira.jboss.com/jira/browse/JBSEAM-906
       */
      public void redirectToLastBrowsedPage() {
  
          // We don't want to redirect to an action, so if the last browsed page was called with an action, remove it
          redirect.getParameters().remove("actionOutcome");
          redirect.getParameters().remove("actionMethod");
  
          // If the last browsed page had a conversation identifier (we assume of a temporary conversation), remove it
          redirect.getParameters().remove("cid");
  
          // We also don't want to redirect the long-running conversation, the caller has ended it already
          redirect.setConversationPropagationEnabled(false);
  
          redirect.returnToCapturedView();
      }
  
      public void redirectToLastBrowsedPageWithConversation() {
          // We don't want to redirect to an action, so if the last browsed page was called with an action, remove it
          redirect.getParameters().remove("actionOutcome");
          redirect.getParameters().remove("actionMethod");
  
          // If the last browsed page had a conversation identifier (we assume of a temporary conversation), remove it
          redirect.getParameters().remove("cid");
  
          System.out.println("############# REDIRECTING WITH CONVERSATION TO : " +redirect.getViewId());
          redirect.returnToCapturedView();
      }
  
      // Just a convenience method for recursive calling
      protected void addDirectoryToPath(List<Node> path, Node directory) {
          path.add(directory);
          if (directory.getParent() != null )
              addDirectoryToPath(path, directory.getParent());
      }
  
  
      @Transactional
      public String prepare() {
  
          // Store the view-id that called this method (as a page action) for return (exit of a later conversation)
          redirect.captureCurrentRequest();
          // TODO: I'm not using captureCurrentView() because it starts a conversation (and it doesn't capture all request parameters)
  
          // Have we been called with a nodeId request parameter, could be document or directory
          if (nodeId != null && !nodeId.equals(wikiRoot.getId())) {
  
              // 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
                  if (currentDirectory != null) currentDocument = currentDirectory.getDefaultDocument();
  
              } 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) {
  
              // 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 = currentDirectory.getDefaultDocument();
                   } 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) {
              currentDirectory = nodeDAO.findArea(areaName);
              if (currentDirectory != null) currentDocument = currentDirectory.getDefaultDocument();
          }
  
          // Fall back to wiki root
          if (currentDirectory== null) currentDirectory = wikiRoot;
  
          // Set the id for later
          nodeId = currentDocument != null ? currentDocument.getId() : currentDirectory.getId();
  
          // Prepare directory path for breadcrumb
          currentDirectoryPath.clear();
          addDirectoryToPath(currentDirectoryPath, currentDirectory);
          Collections.reverse(currentDirectoryPath);
  
          // Return not-null outcome so we can navigate from here
          return "prepared";
      }
  
  }
  
  
  
  1.1      date: 2007/03/07 18:37:37;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/action/DocumentHome.java
  
  Index: DocumentHome.java
  ===================================================================
  package org.jboss.seam.wiki.core.action;
  
  import static javax.faces.application.FacesMessage.SEVERITY_ERROR;
  
  import org.jboss.seam.framework.EntityHome;
  import org.jboss.seam.annotations.*;
  import org.jboss.seam.wiki.core.links.WikiLinkResolver;
  import org.jboss.seam.wiki.core.dao.NodeDAO;
  import org.jboss.seam.wiki.core.dao.UserDAO;
  import org.jboss.seam.wiki.core.model.*;
  import org.jboss.seam.core.FacesMessages;
  import org.jboss.seam.core.Events;
  import org.jboss.seam.core.Conversation;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.Component;
  
  import java.util.List;
  
  @Name("documentHome")
  public class DocumentHome extends EntityHome<Document> {
  
      @RequestParameter
      private Long docId;
  
      @RequestParameter
      private Long parentDirId;
  
      // Pages need this for rendering
      @Out(required = true, scope = ScopeType.CONVERSATION, value = "currentDirectory")
      Directory parentDirectory;
  
      @Out(required = true, scope = ScopeType.CONVERSATION, value = "currentDocument")
      Document currentDocument;
  
      @In
      private FacesMessages facesMessages;
  
      @In
      private NodeBrowser browser;
  
      @In
      private WikiLinkResolver wikiLinkResolver;
  
      @In
      private NodeDAO nodeDAO;
  
      @In
      private UserDAO userDAO;
  
      @In
      private User authenticatedUser;
  
      @In(required = false)
      Node selectedHistoricalNode;
  
      private Document historicalCopy;
      private String formContent;
      private boolean enabledPreview = false;
      private boolean minorRevision = true;
      private List<org.jboss.seam.wiki.core.model.Role> roles;
      private org.jboss.seam.wiki.core.model.Role writableByRole;
      private org.jboss.seam.wiki.core.model.Role readableByRole;
  
      @Override
      public Object getId() {
  
          if (docId == null) {
              return super.getId();
          } else {
              return docId;
          }
      }
  
      @Override
      @Transactional
      public void create() {
          super.create();
  
          // Settings
          GlobalPreferences globalPrefs = (GlobalPreferences) Component.getInstance("globalPrefs");
          minorRevision = !globalPrefs.isDefaultNewRevisionForEditedDocument();
  
          // Load the parent directory
          parentDirectory = nodeDAO.findDirectory(parentDirId);
  
          // Outject current document
          currentDocument = getInstance();
  
          // Load the availale roles and set permission defaults
          roles = userDAO.findRoles();
  
          // Rollback to historical revision?
          if (selectedHistoricalNode != null) getInstance().rollback(selectedHistoricalNode);
  
          // Make a copy
          historicalCopy = new Document(getInstance());
      }
  
      // TODO: Typical exit method to get out of a root or nested conversation, JBSEAM-906
      public void exitConversation(Boolean endBeforeRedirect) {
          Conversation currentConversation = Conversation.instance();
          if (currentConversation.isNested()) {
              // End this nested conversation and return to last rendered view-id of parent
              currentConversation.endAndRedirect(endBeforeRedirect);
          } else {
              // End this root conversation
              currentConversation.end();
              // Return to the view-id that was captured when this conversation started
              if (endBeforeRedirect)
                  browser.redirectToLastBrowsedPage();
              else
                  browser.redirectToLastBrowsedPageWithConversation();
          }
      }
  
      @Override
      public String persist() {
  
          // Validate
          if (!isUniqueWikinameInDirectory() ||
              !isUniqueWikinameInArea()) return null;
  
          // Link the document with a directory
          parentDirectory.addChild(getInstance());
  
          // Set created by user
          getInstance().setCreatedBy(authenticatedUser);
  
          // Set its area number
          getInstance().setAreaNumber(parentDirectory.getAreaNumber());
  
          // Convert and set form content onto entity instance
          getInstance().setContent(
              wikiLinkResolver.convertToWikiLinks(parentDirectory, getFormContent())
          );
  
          System.out.println("#### WRITABLE BY ROLE: " + writableByRole);
  
          return super.persist();
      }
  
  
      @Override
      public String update() {
  
          // Validate
          if (!isUniqueWikinameInDirectory() ||
              !isUniqueWikinameInArea()) return null;
  
          // Convert and set form content onto entity instance
          getInstance().setContent(
              wikiLinkResolver.convertToWikiLinks(parentDirectory, getFormContent())
          );
  
          // Set last modified by user
          getInstance().setLastModifiedBy(authenticatedUser);
  
          Events.instance().raiseEvent("Nodes.menuStructureModified");
  
          // Write history log and prepare a new copy for further modification
          if (!isMinorRevision()) {
              nodeDAO.persistHistoricalNode(historicalCopy);
              getInstance().incrementRevision();
              historicalCopy = new Document(getInstance());
          }
  
          return super.update();
      }
  
      @Override
      public String remove() {
  
          // Unlink the document from its directory
          getInstance().getParent().removeChild(getInstance());
  
          Events.instance().raiseEvent("Nodes.menuStructureModified");
  
          // Delete all history nodes
          nodeDAO.removeHistoricalNodes(getInstance());
  
          return super.remove();
      }
  
      public String getFormContent() {
          // Load the document content and resolve links
          if (formContent == null)
              formContent = wikiLinkResolver.convertFromWikiLinks(parentDirectory, getInstance().getContent());
          return formContent;
      }
  
      public void setFormContent(String formContent) {
          this.formContent = formContent;
      }
  
      public boolean isEnabledPreview() {
          return enabledPreview;
      }
  
      public void setEnabledPreview(boolean enabledPreview) {
          this.enabledPreview = enabledPreview;
          // Convert and set form content onto entity instance
          getInstance().setContent(
              wikiLinkResolver.convertToWikiLinks(parentDirectory, getFormContent())
          );
      }
  
      public boolean isMinorRevision() {
          return minorRevision;
      }
  
      public void setMinorRevision(boolean minorRevision) {
          this.minorRevision = minorRevision;
      }
  
      public List<org.jboss.seam.wiki.core.model.Role> getRoles() {
          return roles;
      }
  
      public org.jboss.seam.wiki.core.model.Role getWritableByRole() {
          return writableByRole;
      }
  
      public void setWritableByRole(org.jboss.seam.wiki.core.model.Role writableByRole) {
          this.writableByRole = writableByRole;
      }
  
      public org.jboss.seam.wiki.core.model.Role getReadableByRole() {
          return readableByRole;
      }
  
      public void setReadableByRole(org.jboss.seam.wiki.core.model.Role readableByRole) {
          this.readableByRole = readableByRole;
      }
  
      // Validation rules for persist(), update(), and remove();
  
      private boolean isUniqueWikinameInDirectory() {
          Node foundNode = nodeDAO.findNodeInDirectory(parentDirectory, getInstance().getWikiname());
          if (foundNode != null && foundNode != getInstance()) {
              facesMessages.addToControlFromResourceBundleOrDefault(
                  "name",
                  SEVERITY_ERROR,
                  getMessageKeyPrefix() + "duplicateName",
                  "This name is already used, please change it."
              );
              return false;
          }
          return true;
      }
  
      private boolean isUniqueWikinameInArea() {
          Node foundNode = nodeDAO.findNodeInArea(parentDirectory.getAreaNumber(), getInstance().getWikiname());
          if (foundNode != null && foundNode != getInstance()) {
              facesMessages.addToControlFromResourceBundleOrDefault(
                  "name",
                  SEVERITY_ERROR,
                  getMessageKeyPrefix() + "duplicateNameInArea",
                  "This name is already used in this area, please change it."
              );
              return false;
          }
          return true;
      }
  
  }
  
  
  



More information about the jboss-cvs-commits mailing list