001    package org.mycore.services.acl;
002    
003    import java.io.IOException;
004    import java.io.Reader;
005    import java.io.StringReader;
006    import java.util.Date;
007    import java.util.HashMap;
008    import java.util.Iterator;
009    import java.util.LinkedList;
010    import java.util.List;
011    import java.util.Map;
012    
013    import org.apache.log4j.Logger;
014    import org.jdom.Document;
015    import org.jdom.Element;
016    import org.jdom.JDOMException;
017    import org.jdom.filter.Filter;
018    import org.jdom.input.SAXBuilder;
019    import org.mycore.access.MCRAccessInterface;
020    import org.mycore.access.mcrimpl.MCRAccessControlSystem;
021    import org.mycore.access.mcrimpl.MCRRuleMapping;
022    import org.mycore.backend.hibernate.tables.MCRACCESS;
023    import org.mycore.backend.hibernate.tables.MCRACCESSPK;
024    import org.mycore.backend.hibernate.tables.MCRACCESSRULE;
025    import org.mycore.common.MCRException;
026    import org.mycore.common.MCRSessionMgr;
027    
028    public class MCRACLXMLProcessing {
029        String uid = MCRSessionMgr.getCurrentSession().getCurrentUserID();;
030        
031        private static Logger LOGGER = Logger.getLogger(MCRACLXMLProcessing.class);
032    
033        public Element accessFilter2XML(String objid, String acpool) {
034            Element filter = new Element("mcr_access_filter");
035            Element objidFilter = new Element("objid");
036            Element acpoolFilter = new Element("acpool");
037    
038            if (objid == null)
039                objid = "";
040    
041            if (acpool == null)
042                acpool = "";
043    
044            objidFilter.addContent(objid);
045            filter.addContent(objidFilter);
046    
047            acpoolFilter.addContent(acpool);
048            filter.addContent(acpoolFilter);
049    
050            return filter;
051        }
052    
053        public Element access2XML(List accessList, boolean withPos) {
054            Element mcrAccessSet = new Element("mcr_access_set");
055    
056            if (accessList == null) {
057                MCRACCESS emptyAccess = new MCRACCESS();
058                MCRACCESSRULE emptyRule = new MCRACCESSRULE();
059                emptyRule.setRid("");
060                emptyAccess.setRule(emptyRule);
061                emptyAccess.setKey(new MCRACCESSPK("", ""));
062                accessList = new LinkedList();
063                accessList.add(emptyAccess);
064            }
065    
066            int i = 0;
067            for (Iterator it = accessList.iterator(); it.hasNext();) {
068                MCRACCESS accessView = (MCRACCESS) it.next();
069    
070                Element mcrAccess = new Element("mcr_access");
071                if (withPos)
072                    mcrAccess.setAttribute("pos", Integer.toString(i));
073    
074                Element ACPOOL = new Element("ACPOOL");
075                ACPOOL.addContent(accessView.getKey().getAcpool());
076    
077                Element OBJID = new Element("OBJID");
078                OBJID.addContent(accessView.getKey().getObjid());
079    
080                Element RID = new Element("RID");
081                RID.addContent(accessView.getRule().getRid());
082    
083                mcrAccess.addContent(ACPOOL);
084                mcrAccess.addContent(OBJID);
085                mcrAccess.addContent(RID);
086    
087                mcrAccessSet.addContent(mcrAccess);
088    
089                i++;
090            }
091            return mcrAccessSet;
092        }
093    
094        public Element ruleSet2Items(List ruleList) {
095            Element items = new Element("items");
096    
097            for (Iterator it = ruleList.iterator(); it.hasNext();) {
098                MCRACCESSRULE rule = (MCRACCESSRULE) it.next();
099    
100                Element item = new Element("item");
101                String rid = rule.getRid();
102                item.setAttribute("value", rid);
103    
104                String descr = rule.getDescription();
105    
106                if (descr != null)
107                    item.setAttribute("label", descr + " ( " + rid + ")");
108                else
109                    item.setAttribute("label", rid);
110    
111                items.addContent(item);
112            }
113    
114            return items;
115        }
116    
117        public Element ruleSet2XML(List ruleList) {
118            Element mcrAccessRuleSet = new Element("mcr_access_rule_set");
119            MCRACLHIBAccess HIBA = new MCRACLHIBAccess();
120    
121            if (ruleList == null) {
122                MCRACCESSRULE emptyRule = new MCRACCESSRULE();
123                emptyRule.setRid("");
124                emptyRule.setRule("");
125                ruleList = new LinkedList();
126                ruleList.add(emptyRule);
127            }
128    
129            int i = 0;
130            for (Iterator it = ruleList.iterator(); it.hasNext();) {
131                MCRACCESSRULE rule = (MCRACCESSRULE) it.next();
132    
133                Element mcrAccessRule = new Element("mcr_access_rule");
134                mcrAccessRule.setAttribute("pos", Integer.toString(i));
135    
136                mcrAccessRule.addContent(new Element("RuleStyle").addContent("plain"));
137    
138                String rid = rule.getRid();
139                mcrAccessRule.addContent(new Element("RID").addContent(rid));
140                mcrAccessRule.addContent(new Element("RULE").addContent(rule.getRule()));
141    
142                String descr = rule.getDescription();
143    
144                if (descr != null)
145                    mcrAccessRule.addContent(new Element("DESCRIPTION").addContent(descr));
146                else
147                    mcrAccessRule.addContent(new Element("DESCRIPTION").addContent(""));
148    
149                if (HIBA.ruleIsInUse(rid).isEmpty()) {
150                    mcrAccessRule.addContent(new Element("inUse").addContent("false"));
151                } else {
152                    mcrAccessRule.addContent(new Element("inUse").addContent("true"));
153                }
154    
155                mcrAccessRuleSet.addContent(mcrAccessRule);
156    
157                i++;
158            }
159    
160            return mcrAccessRuleSet;
161        }
162    
163        public Map findRulesDiff(Document editedRules, Document origRules) throws Exception {
164            Element editedRulesRoot = editedRules.getRootElement();
165            Element origRulesRoot = origRules.getRootElement();
166    
167            Map diffMap = new HashMap();
168    
169            List updateList = new LinkedList();
170            List saveList = new LinkedList();
171            List deleteList = new LinkedList();
172    
173            String rid = "";
174            String editedRuleString = "";
175            String editedDescription = "";
176            String ruleStyle = "";
177    
178            List rulesList = editedRulesRoot.getChildren();
179    
180            Iterator iterator = rulesList.iterator();
181            while (iterator.hasNext()) {
182                MCRACCESSRULE accessRule = new MCRACCESSRULE();
183                Element editedRule = (Element) iterator.next();
184    
185                final String pos = editedRule.getAttributeValue("pos");
186                ruleStyle = editedRule.getChildText("RuleStyle");
187                rid = editedRule.getChildText("RID");
188                editedRuleString = editedRule.getChildText("RULE");
189                editedDescription = editedRule.getChildText("DESCRIPTION");
190    
191                LOGGER.debug("Edited Pos: " + pos);
192                LOGGER.debug("Edited RID: " + rid);
193                LOGGER.debug("Edited Rule: " + editedRuleString);
194                LOGGER.debug("Edited Desc: " + editedDescription);
195    
196                if (editedDescription == null)
197                    editedDescription = "";
198    
199                if (ruleStyle.equals("xml"))
200                    editedRuleString = ruleFromXML(editedRuleString);
201    
202                accessRule.setRid(rid);
203                accessRule.setRule(editedRuleString);
204                accessRule.setDescription(editedDescription);
205    
206                // pos null or empty means new rule
207                if (pos == null || pos.equals("")) {
208                    LOGGER.debug("Adding new rule to save list!");
209                    saveList.add(accessRule);
210                } else {
211                    Filter posFilter = new Filter() {
212                        public boolean matches(Object arg0) {
213                            if (((Element) arg0).getAttributeValue("pos").equals(pos)) {
214                                return true;
215                            } else
216                                return false;
217                        }
218                    };
219    
220                    Element origRule = (Element) origRulesRoot.removeContent(posFilter).get(0);
221                    String origRuleString = origRule.getChildText("RULE");
222                    String origDescription = origRule.getChildText("DESCRIPTION");
223    
224                    // find some changes in rule String or description
225                    if (!editedRuleString.equals(origRuleString) || !editedDescription.equals(origDescription)) {
226                        LOGGER.debug("Adding rule " + rid + " to update list!");
227    
228                        updateList.add(accessRule);
229                    }
230                }
231            }
232    
233            // remainder in origRules are deleted rules
234            iterator = origRulesRoot.getChildren().iterator();
235            while (iterator.hasNext()) {
236                rid = ((Element) iterator.next()).getChildText("RID");
237                LOGGER.debug("Adding rule " + rid + " to delete list!");
238                deleteList.add(rid);
239            }
240    
241            diffMap.put("update", updateList);
242            diffMap.put("save", saveList);
243            diffMap.put("delete", deleteList);
244    
245            return diffMap;
246        }
247    
248        private String ruleFromXML(String rule) throws JDOMException, IOException {
249            SAXBuilder saxBuilder = new SAXBuilder("org.apache.xerces.parsers.SAXParser");
250            Reader stringReader = new StringReader(rule);
251            Document jdomDocument = saxBuilder.build(stringReader);
252            MCRAccessInterface AI = MCRAccessControlSystem.instance();
253            // new MCRAccessCommands().
254    
255            return AI.getNormalizedRuleString(jdomDocument.getRootElement());
256        }
257    
258        public Map findAccessDiff(Document editedAcces, Document origAccess) throws Exception {
259            Element editedAccessRoot = editedAcces.getRootElement();
260            Map diffMap = new HashMap();
261    
262            LOGGER.info("******* Filter not changed!!");
263    
264            List editedElemList = editedAccessRoot.getChildren();
265            Element origAccessRoot = origAccess.getRootElement();
266    
267            List updateList = new LinkedList();
268            List saveList = new LinkedList();
269            List deleteList = new LinkedList();
270    
271            for (Iterator iter = editedElemList.iterator(); iter.hasNext();) {
272                Element currentElem = (Element) iter.next();
273                final String position = currentElem.getAttributeValue("pos");
274    
275                if (position == null) {
276                    String currentACPool = currentElem.getChildText("ACPOOL");
277                    String currentObjID = currentElem.getChildText("OBJID");
278                    String currentRID = currentElem.getChildText("RID");
279    
280                    saveList.add(createRuleMapping(currentRID, currentACPool, currentObjID));
281                } else {
282                    Filter posFilter = new Filter() {
283                        public boolean matches(Object arg0) {
284                            if (((Element) arg0).getAttributeValue("pos").equals(position)) {
285                                return true;
286                            } else
287                                return false;
288                        }
289                    };
290    
291                    List matchingList = origAccessRoot.removeContent(posFilter);
292                    if (matchingList.size() > 1)
293                        throw new Exception("Position number in access XML not unique!!");
294    
295                    Element origElem = (Element) matchingList.get(0);
296                    String currentACPool = currentElem.getChildText("ACPOOL");
297                    String currentObjID = currentElem.getChildText("OBJID");
298                    String currentRID = currentElem.getChildText("RID");
299    
300                    String origACPool = origElem.getChildText("ACPOOL");
301                    String origObjID = origElem.getChildText("OBJID");
302                    String origRID = origElem.getChildText("RID");
303    
304                    if (!currentACPool.equals(origACPool) || !currentObjID.equals(origObjID)) {
305                        saveList.add(createRuleMapping(currentRID, currentACPool, currentObjID));
306                        deleteList.add(createRuleMapping(origRID, origACPool, origObjID));
307                    } else if (!currentRID.equals(origRID)) {
308                        updateList.add(createRuleMapping(currentRID, currentACPool, currentObjID));
309                    }
310                }
311            }
312    
313            for (Iterator iter = origAccessRoot.getChildren().iterator(); iter.hasNext();) {
314                Element origElem = (Element) iter.next();
315    
316                String origACPool = origElem.getChildText("ACPOOL");
317                String origObjID = origElem.getChildText("OBJID");
318                String origRID = origElem.getChildText("RID");
319    
320                deleteList.add(createRuleMapping(origRID, origACPool, origObjID));
321    
322            }
323    
324            diffMap.put("update", updateList);
325            diffMap.put("save", saveList);
326            diffMap.put("delete", deleteList);
327    
328            return diffMap;
329        }
330    
331        public Element findDiffAsXML(Document editedAcces, Document origAccess) throws Exception {
332            Map diffMap = findAccessDiff(editedAcces, origAccess);
333    
334            Element diff = new Element("Diff_list");
335    
336            Element update = makeElem((List) diffMap.get("update"), "update");
337            Element save = makeElem((List) diffMap.get("save"), "save");
338            Element delete = makeElem((List) diffMap.get("delete"), "delete");
339    
340            diff.addContent(update);
341            diff.addContent(save);
342            diff.addContent(delete);
343    
344            return diff;
345        }
346    
347        private Element makeElem(List list, String rootName) {
348            Element root = new Element(rootName);
349            Element mcr_access_set = new Element("mcr_access_set");
350            int i = 0;
351    
352            for (Iterator it = list.iterator(); it.hasNext();) {
353                MCRRuleMapping ruleMapping = (MCRRuleMapping) it.next();
354    
355                Element mcr_access = new Element("mcr_access");
356                mcr_access.setAttribute("pos", Integer.toString(i));
357    
358                Element ACPOOL = new Element("ACPOOL");
359                ACPOOL.addContent(ruleMapping.getPool());
360    
361                Element OBJID = new Element("OBJID");
362                OBJID.addContent(ruleMapping.getObjId());
363    
364                Element RID = new Element("RID");
365                RID.addContent(ruleMapping.getRuleId());
366    
367                mcr_access.addContent(ACPOOL);
368                mcr_access.addContent(OBJID);
369                mcr_access.addContent(RID);
370    
371                mcr_access_set.addContent(mcr_access);
372                i++;
373            }
374    
375            return root.addContent(mcr_access_set);
376    
377        }
378    
379        public MCRRuleMapping createRuleMapping(String rid, String acpool, String objid) {
380            MCRRuleMapping ruleMapping = new MCRRuleMapping();
381            
382            ruleMapping.setCreator(uid);
383            ruleMapping.setCreationdate(new Date());
384            ruleMapping.setPool(acpool);
385            ruleMapping.setRuleId(rid);
386            ruleMapping.setObjId(objid);
387            return ruleMapping;
388        }
389    }