001    package org.mycore.frontend.wcms;
002    
003    import java.io.IOException;
004    import java.util.HashMap;
005    import java.util.Iterator;
006    import java.util.List;
007    
008    import org.apache.log4j.Logger;
009    import org.jdom.Document;
010    import org.jdom.Element;
011    import org.jdom.JDOMException;
012    import org.jdom.output.DOMOutputter;
013    import org.jdom.xpath.XPath;
014    import org.mycore.access.MCRAccessInterface;
015    import org.mycore.access.MCRAccessManager;
016    import org.mycore.common.MCRException;
017    import org.mycore.frontend.MCRLayoutUtilities;
018    import org.mycore.user.MCRUser;
019    import org.mycore.user.MCRUserMgr;
020    
021    public class MCRWCMSUtilities {
022    
023        final static String WRITE_PERMISSION_WEBPAGE = "write";
024    
025        final static String PERM_RIGHTS_MANAGEMENT_READ_ACCESS = "manage-readaccess-website";
026    
027        final static String PERM_RIGHTS_MANAGEMENT_WCMS_ACCESS = "manage-wcmsaccess";
028    
029        final static XPath xpath;
030        static {
031            try {
032                xpath = XPath.newInstance("*[@href and not(@type='extern')]");
033            } catch (JDOMException e) {
034                throw new MCRException("", e);
035            }
036        }
037    
038        private final static Logger LOGGER = Logger.getLogger(MCRWCMSUtilities.class);
039    
040        /**
041         * Verifies a given webpage-ID (//item/@href) from navigation.xml on write
042         * permission, based on ACL-System. To be used by XSL with
043         * Xalan-Java-Extension-Call
044         * 
045         * @param webpageID
046         * @return True if access granted, false if access is forbidden
047         * @throws JDOMException
048         * @throws IOException
049         */
050        public static boolean writeAccess(String webpageID) {
051            long startTime = System.currentTimeMillis();
052            boolean access = MCRLayoutUtilities.getAccess(webpageID, getWritePermissionWebpage(), MCRLayoutUtilities.ONETRUE_ALLTRUE);
053            LOGGER.debug("checked write access for webpage=" + webpageID + "=" + access + ": took " + MCRLayoutUtilities.getDuration(startTime) + " msec.");
054            return access;
055        }
056    
057        /**
058         * Returns a filtered navigation.xml, according to current logged in users
059         * WCMS-Write permissions. Only menu items that are permitted to write on
060         * are given back.
061         * 
062         * @return org.w3c.dom.Document with writable menu items.
063         * @throws JDOMException
064         * @throws IOException
065         */
066        public static org.w3c.dom.Document getWritableNavi() throws JDOMException, IOException {
067            return getWritableNaviImpl("");
068        }
069    
070        /**
071         * Returns a filtered navigation.xml, according to the given user WCMS-Write
072         * permissions. Only menu items that are permitted to write on are given
073         * back.
074         * 
075         * @param userID,
076         *            a MCRUserID
077         * @return org.w3c.dom.Document with writable menu items.
078         * @throws JDOMException
079         * @throws IOException
080         */
081        public static org.w3c.dom.Document getWritableNavi(String userID) throws JDOMException, IOException {
082            return getWritableNaviImpl(userID);
083        }
084    
085        private static org.w3c.dom.Document getWritableNaviImpl(String userID) throws JDOMException, IOException {
086            Element origNavi = new Element("root");
087            origNavi.addContent((Element) MCRLayoutUtilities.getNavi().getRootElement().clone());
088            Document writableNavi = new Document(new Element("root"));
089            buildWritableNavi(origNavi, writableNavi, userID);
090            return new DOMOutputter().output(writableNavi);
091        }
092    
093        /**
094         * Returns a boolean, signalling if the user has at least write access for 1
095         * item.
096         * 
097         * @return true, if access is granted for at least 1 item OR false, if the
098         *         user has no access for any item
099         * @throws JDOMException
100         */
101        protected static boolean writeAccessGeneral() {
102            Element navi = (new Element("root")).addContent((Element) MCRLayoutUtilities.getNavi().getRootElement().clone());
103            long startTime = System.currentTimeMillis();
104            HashMap accessMap = new HashMap();
105            getWriteAccessGeneral(navi, accessMap);
106            boolean access = !accessMap.isEmpty();
107            LOGGER.debug("checked write access in general=" + access + ": took " + MCRLayoutUtilities.getDuration(startTime) + " msec.");
108            return access;
109        }
110    
111        /**
112         * The implementation for writeAccessGeneral()
113         * 
114         * @param navigation
115         * @return
116         * @throws JDOMException
117         */
118        private static void getWriteAccessGeneral(Element navigation, HashMap accessMap) {
119            List childs = null;
120            try {
121                childs = xpath.selectNodes(navigation);
122            } catch (JDOMException e) {
123                e.printStackTrace();
124            }
125            Iterator childIter = childs.iterator();
126            while (accessMap.isEmpty() && childIter.hasNext()) {
127                Element child = (Element) childIter.next();
128                boolean access = MCRLayoutUtilities.itemAccess(getWritePermissionWebpage(), child, false);
129                if (access)
130                    accessMap.put("access", "true");
131                else
132                    getWriteAccessGeneral(child, accessMap);
133            }
134        }
135    
136        /**
137         * Returns a DOM-Object containing only items the user have write access
138         * for. The writable items structure will be put into writableNavi.
139         * 
140         * @param origNavi
141         *            The navigation.xml with an additional dummy root Element
142         * @param writableNavi
143         *            A Document with only o root tag to be filled with writeable
144         *            items
145         * @throws JDOMException
146         * @throws IOException
147         */
148        private static void buildWritableNavi(Element origNavi, Document writableNavi, String userID) throws JDOMException, IOException {
149            List childs = xpath.selectNodes(origNavi);
150            Iterator childIter = childs.iterator();
151            while (childIter.hasNext()) {
152                Element child = (Element) childIter.next();
153                boolean access = false;
154                if (!userID.equals("")) {
155                    MCRUser user = MCRUserMgr.instance().retrieveUser(userID);
156                    access = MCRLayoutUtilities.itemAccess(getWritePermissionWebpage(), child, false, user);
157                } else
158                    access = MCRLayoutUtilities.itemAccess(getWritePermissionWebpage(), child, false);
159                if (access) {
160                    // mark root item, to be able proccessing by XSL
161                    child.setAttribute("ancestorLabels", MCRLayoutUtilities.getAncestorLabels(child));
162                    // cut node and add to target XML
163                    writableNavi.getRootElement().addContent(child.detach());
164                } else
165                    buildWritableNavi(child, writableNavi, userID);
166            }
167        }
168    
169        public static String getWritePermissionWebpage() {
170            return WRITE_PERMISSION_WEBPAGE;
171        }
172    
173        public static String getPermRightsManagementReadAccess() {
174            return PERM_RIGHTS_MANAGEMENT_READ_ACCESS;
175        }
176    
177        public static String getPermRightsManagementWCMSAccess() {
178            return PERM_RIGHTS_MANAGEMENT_WCMS_ACCESS;
179        }
180    
181        public static boolean manageReadAccess() {
182            return MCRAccessManager.getAccessImpl().checkPermission(MCRWCMSUtilities.getPermRightsManagementReadAccess());
183        }
184    
185        public static boolean manageWCMSAccess() {
186            return MCRAccessManager.getAccessImpl().checkPermission(MCRWCMSUtilities.getPermRightsManagementWCMSAccess());
187        }
188    
189    }