001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2001-2007 JSPWiki development group
005:
006: This program is free software; you can redistribute it and/or modify
007: it under the terms of the GNU Lesser General Public License as published by
008: the Free Software Foundation; either version 2.1 of the License, or
009: (at your option) any later version.
010:
011: This program is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: GNU Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public License
017: along with this program; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: package com.ecyrd.jspwiki.auth.permissions;
021:
022: import java.util.WeakHashMap;
023:
024: import com.ecyrd.jspwiki.WikiPage;
025:
026: /**
027: * Provides a factory for Permission objects. Since the Permissions are immutable,
028: * and creating them takes a bit of time, caching them makes sense.
029: * <p>
030: * This class stores the permissions in a static HashMap.
031: * @author Janne Jalkanen
032: * @since 2.5.54
033: */
034: public class PermissionFactory {
035: /**
036: * This is a WeakHashMap<Integer,PagePermission>, which stores the
037: * cached page permissions.
038: */
039: private static WeakHashMap c_cache = new WeakHashMap();
040:
041: /**
042: * Get a permission object for a WikiPage and a set of actions.
043: *
044: * @param page The page object.
045: * @param actions A list of actions.
046: * @return A PagePermission object, presenting this page+actions combination.
047: */
048: public static final PagePermission getPagePermission(WikiPage page,
049: String actions) {
050: return getPagePermission(page.getWiki(), page.getName(),
051: actions);
052: }
053:
054: /**
055: * Get a permission object for a WikiPage and a set of actions.
056: *
057: * @param page The name of the page.
058: * @param actions A list of actions.
059: * @return A PagePermission object, presenting this page+actions combination.
060: */
061: public static final PagePermission getPagePermission(String page,
062: String actions) {
063: return getPagePermission("", page, actions);
064: }
065:
066: /**
067: * Get a page permission based on a wiki, page, and actions.
068: *
069: * @param wiki The name of the wiki. Can be an empty string, but must not be null.
070: * @param page The page name
071: * @param actions A list of actions.
072: * @return A PagePermission object.
073: */
074: private static final PagePermission getPagePermission(String wiki,
075: String page, String actions) {
076: PagePermission perm;
077: //
078: // Since this is pretty speed-critical, we try to avoid the StringBuffer creation
079: // overhead by XORring the hashcodes. However, if page name length > 32 characters,
080: // this might result in two same hashCodes.
081: // FIXME: Make this work for page-name lengths > 32 characters (use the alt implementation
082: // if page.length() > 32?)
083: // Alternative implementation below, but it does create an extra StringBuffer.
084: //String key = wiki+":"+page+":"+actions;
085:
086: Integer key = new Integer(wiki.hashCode() ^ page.hashCode()
087: ^ actions.hashCode());
088:
089: //
090: // It's fine if two threads update the cache, since the objects mean the same
091: // thing anyway. And this avoids nasty blocking effects.
092: //
093: synchronized (c_cache) {
094: perm = (PagePermission) c_cache.get(key);
095: }
096:
097: if (perm == null) {
098: if (wiki.length() > 0)
099: page = wiki + ":" + page;
100: perm = new PagePermission(page, actions);
101:
102: synchronized (c_cache) {
103: c_cache.put(key, perm);
104: }
105: }
106:
107: return perm;
108: }
109:
110: }
|