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 }