0001: /* Copyright 2001 The JA-SIG Collaborative. All rights reserved.
0002: * See license distributed with this file and
0003: * available online at http://www.uportal.org/license.html
0004: */
0005:
0006: package org.jasig.portal.channels.groupsmanager;
0007:
0008: import java.util.ArrayList;
0009: import java.util.Calendar;
0010: import java.util.Collection;
0011: import java.util.HashMap;
0012: import java.util.Iterator;
0013:
0014: import javax.xml.parsers.DocumentBuilderFactory;
0015: import javax.xml.parsers.ParserConfigurationException;
0016:
0017: import org.jasig.portal.ChannelStaticData;
0018: import org.jasig.portal.EntityTypes; /* @todo remove when groups/EntityTypes is removed */
0019: import org.jasig.portal.IPermissible;
0020: import org.jasig.portal.channels.groupsmanager.permissions.GroupsManagerAdminPermissions;
0021: import org.jasig.portal.channels.groupsmanager.permissions.GroupsManagerDefaultPermissions;
0022: import org.jasig.portal.groups.IEntity;
0023: import org.jasig.portal.groups.IEntityGroup;
0024: import org.jasig.portal.groups.IGroupMember;
0025: import org.jasig.portal.security.IAuthorizationPrincipal;
0026: import org.jasig.portal.security.IPermission;
0027: import org.jasig.portal.security.IUpdatingPermissionManager;
0028: import org.jasig.portal.services.AuthorizationService;
0029: import org.jasig.portal.services.EntityNameFinderService;
0030: import org.jasig.portal.services.EntityPropertyRegistry;
0031: import org.jasig.portal.services.GroupService;
0032: import org.apache.commons.logging.Log;
0033: import org.apache.commons.logging.LogFactory;
0034: import org.w3c.dom.Document;
0035: import org.w3c.dom.Element;
0036: import org.w3c.dom.Node;
0037: import org.w3c.dom.NodeList;
0038:
0039: /**
0040: * Contains a groups of static methods used to centralize the generation and
0041: * retrieval of xml elements for groups and entities.
0042: * @author Don Fracapane
0043: * @version $Revision: 36656 $
0044: */
0045: public class GroupsManagerXML implements GroupsManagerConstants {
0046: private static final Log log = LogFactory
0047: .getLog(GroupsManagerXML.class);
0048: private static int UID = 0;
0049:
0050: /**
0051: * Returns a Document with an element for each IEntityType that has a root group.
0052: * @param sessionData CGroupsManagerSessionData
0053: * @return Document
0054: */
0055: public static Document getGroupsManagerXml(
0056: CGroupsManagerSessionData sessionData) {
0057: Element rootGroupElement;
0058: Document viewDoc = getNewDocument();
0059: sessionData.model = viewDoc;
0060: Element viewRoot = viewDoc.createElement("CGroupsManager");
0061: viewDoc.appendChild(viewRoot);
0062: //don't create permission elements for an admin user
0063: Utility.logMessage("DEBUG",
0064: "GroupsManagerXML::getGroupsManagerXML(): sessionData.isAdminUser = "
0065: + sessionData.isAdminUser);
0066: if (sessionData.gmPermissions == null) {
0067: if (sessionData.isAdminUser)
0068: sessionData.gmPermissions = GroupsManagerAdminPermissions
0069: .getInstance();
0070: else
0071: sessionData.gmPermissions = GroupsManagerDefaultPermissions
0072: .getInstance();
0073: }
0074: Element etRoot = getEntityTypesXml(viewDoc);
0075: viewRoot.appendChild(etRoot);
0076: Element rootGroupsElem = GroupsManagerXML.createElement(
0077: GROUP_TAGNAME, viewDoc, true);
0078: //id=0 distinguishes the root groups element
0079: rootGroupsElem.setAttribute("id", "0");
0080: rootGroupsElem.setAttribute("expanded", "true");
0081: Element rdfElem = createRdfElement(null, viewDoc);
0082: rootGroupsElem.appendChild(rdfElem);
0083: viewRoot.appendChild(rootGroupsElem);
0084: try {
0085: // name and class for entity types with root group
0086: HashMap entTypes = getEntityTypes();
0087: // next line initializes the unportected subset of session data
0088: CGroupsManagerUnrestrictedSessionData unrsd = sessionData
0089: .getUnrestrictedData();
0090: Iterator entTypeKeys = entTypes.keySet().iterator();
0091: while (entTypeKeys.hasNext()) {
0092: Object key = entTypeKeys.next();
0093: Class entType = (Class) entTypes.get(key);
0094: IEntityGroup rootGrp = GroupService
0095: .getRootGroup(entType);
0096: rootGroupElement = getGroupMemberXml(rootGrp, true,
0097: null, unrsd);
0098: rootGroupElement.setAttribute("editable", String
0099: .valueOf(rootGrp.isEditable()));
0100: rootGroupsElem.appendChild(rootGroupElement);
0101: }
0102: } catch (Exception e) {
0103: Utility.logMessage("ERROR",
0104: "GroupsManagerXML::getGroupsManagerXML(): ERROR"
0105: + e, e);
0106: }
0107: return viewDoc;
0108: }
0109:
0110: /**
0111: * Creates an element for the provided Document. Alternatively, can
0112: * set default values.
0113: * @param name
0114: * @param xmlDoc
0115: * @param setGrpDefault
0116: * @return Element
0117: */
0118: public static Element createElement(String name, Document xmlDoc,
0119: boolean setGrpDefault) {
0120: //List of common attributes
0121: //grpRoot.setAttribute("editable", "false");
0122: //grpRoot.setAttribute("entityType", "org.jasig.portal.security.IPerson");
0123: //grpRoot.setAttribute("expanded", "false");
0124: //grpRoot.setAttribute("hasMembers", "false");
0125: //grpRoot.setAttribute("id", "0");
0126: //grpRoot.setAttribute("key", "");
0127: //grpRoot.setAttribute("selected", "false");
0128: //grpRoot.setAttribute("type", "org.jasig.portal.groups.IEntityGroup");
0129: Element grpRoot = xmlDoc.createElement(name);
0130: grpRoot.setAttribute("selected", "false");
0131: // set default values
0132: if (setGrpDefault) {
0133: grpRoot.setAttribute("id", "");
0134: grpRoot.setAttribute("expanded", "false");
0135: }
0136: return grpRoot;
0137: }
0138:
0139: /**
0140: * Returns an RDF element for the provided Document
0141: * @param entGrp IEntityGroup
0142: * @param xmlDoc Document
0143: * @return Element
0144: */
0145: public static Element createRdfElement(IEntityGroup entGrp,
0146: Document xmlDoc) {
0147: String entName;
0148: String entDesc;
0149: String entCreator;
0150: if (entGrp == null) {
0151: // use default values
0152: entName = ROOT_GROUP_TITLE;
0153: entDesc = ROOT_GROUP_DESCRIPTION;
0154: entCreator = "Default";
0155: } else {
0156: // get values from IEntityGroup
0157: entName = entGrp.getName();
0158: entDesc = entGrp.getDescription();
0159: if (entDesc == null) {
0160: entDesc = new String();
0161: }
0162: entCreator = GroupsManagerXML.getEntityName(
0163: ENTITY_CLASSNAME, entGrp.getCreatorID());
0164: }
0165: //* Maybe I should have all parms in a java.util.HashMap
0166: Element rdfElem = xmlDoc.createElement("rdf:RDF");
0167: rdfElem.setAttribute("xmlns:dc",
0168: "http://purl.org/dc/elements/1.1/");
0169: rdfElem.setAttribute("xmlns:rdf",
0170: "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
0171: Utility
0172: .logMessage("DEBUG",
0173: "GroupsManagerXML::createRdfElement(): CREATING ELEMENT RDF DESCRIPTION");
0174: Element rdfDesc = xmlDoc.createElement("rdf:Description");
0175: Utility
0176: .logMessage("DEBUG",
0177: "GroupsManagerXML::createRdfElement(): CREATING ELEMENT DCTITLE");
0178: Element dcTitle = xmlDoc.createElement("dc:title");
0179: dcTitle.appendChild(xmlDoc.createTextNode(entName));
0180: rdfDesc.appendChild(dcTitle);
0181: Utility
0182: .logMessage("DEBUG",
0183: "GroupsManagerXML::createRdfElement(): CREATING ELEMENT dcDESCRIPTION");
0184: Element dcDescription = xmlDoc.createElement("dc:description");
0185: dcDescription.appendChild(xmlDoc.createTextNode(entDesc));
0186: rdfDesc.appendChild(dcDescription);
0187: Utility
0188: .logMessage("DEBUG",
0189: "GroupsManagerXML::createRdfElement(): CREATING ELEMENT dcCREATOR");
0190: Element dcCreator = xmlDoc.createElement("dc:creator");
0191: Utility
0192: .logMessage("DEBUG",
0193: "GroupsManagerXML::createRdfElement(): APPENDING TO dcCREATOR");
0194: dcCreator.appendChild(xmlDoc.createTextNode(entCreator));
0195: Utility
0196: .logMessage("DEBUG",
0197: "GroupsManagerXML::createRdfElement(): APPENDING TO RDFDESC");
0198: rdfDesc.appendChild(dcCreator);
0199: Utility
0200: .logMessage("DEBUG",
0201: "GroupsManagerXML::createRdfElement(): APPENDING TO RDF");
0202: rdfElem.appendChild(rdfDesc);
0203: return rdfElem;
0204: }
0205:
0206: /**
0207: * Creates permissions to a group for the current user and generates permission elements
0208: * @param sessionData CGroupsManagerSessionData
0209: * @param childEntGrp IEntityGroup
0210: * @throws Exception
0211: */
0212: public static void createPermissions(
0213: CGroupsManagerSessionData sessionData,
0214: IEntityGroup childEntGrp) throws Exception {
0215: /** Grant all permissions for a group to the current user
0216: */
0217: ChannelStaticData staticData = sessionData.staticData;
0218: Document model = sessionData.model;
0219: ArrayList perms = new ArrayList();
0220: IUpdatingPermissionManager upm = AuthorizationService
0221: .instance().newUpdatingPermissionManager(OWNER);
0222: IAuthorizationPrincipal ap = staticData
0223: .getAuthorizationPrincipal();
0224: Utility.logMessage("DEBUG",
0225: "GroupManagerXML::createPermissions(): The IAuthorizationPrincipal: "
0226: + ap);
0227: String[] activities = ((IPermissible) Class.forName(OWNER)
0228: .newInstance()).getActivityTokens();
0229: IPermission prm;
0230: for (int a = 0; a < activities.length; a++) {
0231: prm = upm.newPermission(ap);
0232: prm.setActivity(activities[a]);
0233: prm.setTarget(childEntGrp.getKey());
0234: prm.setType("GRANT");
0235: perms.add(prm);
0236: }
0237: upm.addPermissions((IPermission[]) perms
0238: .toArray(new IPermission[perms.size()]));
0239:
0240: // create permission elements
0241: NodeList principals = model.getDocumentElement()
0242: .getElementsByTagName("principal");
0243: Element princElem = (Element) principals.item(0);
0244: for (int p = 0; p < perms.size(); p++) {
0245: prm = (IPermission) perms.get(p);
0246: Element permElem = GroupsManagerXML.getPermissionXml(model,
0247: prm.getPrincipal(), prm.getActivity(), prm
0248: .getType(), prm.getTarget());
0249: princElem.appendChild(permElem);
0250: }
0251: }
0252:
0253: /**
0254: * Expands an element
0255: * @param expandedElem Element
0256: * @param sd CGroupsManagerUnrestrictedSessionData
0257: */
0258: public static void expandGroupElementXML(Element expandedElem,
0259: CGroupsManagerUnrestrictedSessionData sd) {
0260: //Utility.printElement(expandElem,"Group to be expanded was found (not null): \n" );
0261: boolean hasMembers = (expandedElem.getAttribute("hasMembers")
0262: .equals("true"));
0263: Utility.logMessage("DEBUG",
0264: "ExpandGroup::execute(): Expanded element has Members = "
0265: + hasMembers);
0266:
0267: if (hasMembers) {
0268: expandedElem.setAttribute("expanded", "true");
0269: Utility
0270: .logMessage("DEBUG",
0271: "ExpandGroup::execute(): About to retrieve children");
0272: // Have to check for non persistent search element before doing retrieval
0273: IGroupMember entGrp = (!isPersistentGroup(expandedElem) ? null
0274: : (IGroupMember) retrieveGroup(expandedElem
0275: .getAttribute("key")));
0276: GroupsManagerXML.getGroupMemberXml(entGrp, true,
0277: expandedElem, sd);
0278: //Utility.printDoc(xmlDoc, "renderXML: +++++++++ After children are retrieved +++++++++");
0279: }
0280: }
0281:
0282: /**
0283: * Returns an element holding the user's permissions used to determine access
0284: * privileges in the Groups Manager channel.
0285: * @param sd
0286: * @param apRoot
0287: * @param xmlDoc
0288: * @return Element
0289: */
0290: public static Element getAuthorizationXml(ChannelStaticData sd,
0291: Element apRoot, Document xmlDoc) {
0292: IAuthorizationPrincipal ap = sd.getAuthorizationPrincipal();
0293: String princTagname = "principal";
0294: if (ap != null && apRoot == null) {
0295: apRoot = xmlDoc.createElement(princTagname);
0296: apRoot.setAttribute("token", ap.getPrincipalString());
0297: apRoot.setAttribute("type", ap.getType().getName());
0298: String name = ap.getKey();
0299: try {
0300: name = EntityNameFinderService.instance()
0301: .getNameFinder(ap.getType()).getName(name);
0302: } catch (Exception e) {
0303: Utility.logMessage("ERROR", e.toString(), e);
0304: }
0305: apRoot.setAttribute("name", name);
0306: }
0307: try {
0308: // owner, activity, target
0309: IPermission[] perms = ap.getAllPermissions(OWNER, null,
0310: null);
0311: for (int yy = 0; yy < perms.length; yy++) {
0312: Element prm = getPermissionXml(xmlDoc, perms[yy]
0313: .getPrincipal(), perms[yy].getActivity(),
0314: perms[yy].getType(), perms[yy].getTarget());
0315: apRoot.appendChild(prm);
0316: }
0317: } catch (org.jasig.portal.AuthorizationException ae) {
0318: Utility.logMessage("ERROR",
0319: "GroupsManagerXML::getAuthorzationXml: authorization exception "
0320: + ae.getMessage(), ae);
0321: }
0322: return apRoot;
0323: }
0324:
0325: /**
0326: * Returns an element from an xml document for a unique id. An error is
0327: * displayed if more than one element is found.
0328: * @param aDoc
0329: * @param id
0330: * @return Element
0331: */
0332: public static Element getElementById(Document aDoc, String id) {
0333: int i;
0334: Collection elems = new java.util.ArrayList();
0335: Element elem = null;
0336: Element retElem = null;
0337: org.w3c.dom.NodeList nList;
0338: String tagname = ENTITY_TAGNAME;
0339: boolean isDone = false;
0340: while (!isDone) {
0341: nList = aDoc.getElementsByTagName(tagname);
0342: for (i = 0; i < nList.getLength(); i++) {
0343: elem = (Element) nList.item(i);
0344: if (elem.getAttribute("id").equals(id)) {
0345: elems.add(elem);
0346: }
0347: }
0348: if (tagname.equals(ENTITY_TAGNAME)) {
0349: tagname = GROUP_TAGNAME;
0350: } else {
0351: isDone = true;
0352: }
0353: if (elems.size() != 1) {
0354: if (elems.size() > 1) {
0355: log
0356: .error("GroupsManagerXML::getElementById: More than one element found for Id: "
0357: + id);
0358: }
0359: } else {
0360: retElem = (Element) elems.iterator().next();
0361: }
0362: }
0363: return retElem;
0364: }
0365:
0366: /**
0367: * Returns an Element from a Document for a tagname and element id
0368: * @param aDoc
0369: * @param tagname
0370: * @param id
0371: * @return Element
0372: */
0373: public static Element getElementByTagNameAndId(Document aDoc,
0374: String tagname, String id) {
0375: int i;
0376: Element elem = null;
0377: Element selElem = null;
0378: org.w3c.dom.NodeList nList = aDoc.getElementsByTagName(tagname);
0379: for (i = 0; i < nList.getLength(); i++) {
0380: elem = (Element) nList.item(i);
0381: if (elem.getAttribute("id").equals(id)) {
0382: selElem = elem;
0383: break;
0384: }
0385: }
0386: return selElem;
0387: }
0388:
0389: /**
0390: * Returns the value of an element for a given name
0391: * @param anElem Element
0392: * @param tagname String
0393: * @return String
0394: */
0395: public static String getElementValueForTagName(Element anElem,
0396: String tagname) {
0397: Utility
0398: .logMessage(
0399: "DEBUG",
0400: "GroupsManagerXML:getElementValueForTagName(): retrieve element value for tagname: "
0401: + tagname);
0402: String retValue = null;
0403: NodeList nList = anElem.getElementsByTagName(tagname);
0404: if (nList.getLength() > 0) {
0405: retValue = nList.item(0).getFirstChild().getNodeValue();
0406: }
0407: retValue = (retValue != null ? retValue : "");
0408: Utility.logMessage("DEBUG",
0409: "GroupsManagerXML:getElementValueForTagName(): tagname "
0410: + tagname + " = " + retValue);
0411: return retValue;
0412: }
0413:
0414: /**
0415: * Returns a name from the EntityNameFinderService, for a key and class
0416: * @param typClass
0417: * @param aKey
0418: * @return String
0419: */
0420: public static String getEntityName(Class typClass, String aKey) {
0421: //if (aKey != null){ return "BOGUS_ENTITY_NAME";}
0422: String entName = "";
0423: String msg;
0424: long time1 = Calendar.getInstance().getTime().getTime();
0425: long time2 = 0;
0426: Utility
0427: .logMessage(
0428: "DEBUG",
0429: "GroupsManagerXML.getEntityName(Class,String): Retrieving entity for entityType: "
0430: + typClass.getName() + " key: " + aKey);
0431: try {
0432: entName = EntityNameFinderService.instance().getNameFinder(
0433: typClass).getName(aKey);
0434: } catch (Exception e) {
0435: Utility.logMessage("ERROR",
0436: "GroupsManagerXML.getEntityName(Class,String): ERROR retrieving entity "
0437: + e, e);
0438: }
0439: time2 = Calendar.getInstance().getTime().getTime();
0440: msg = "GroupsManagerXML.getEntityName(Class,String) timer: "
0441: + String.valueOf(time2 - time1) + " ms total";
0442: Utility.logMessage("DEBUG", msg);
0443: Utility.logMessage("DEBUG",
0444: "GroupsManagerXML.getEntityName(Class,String): typClass/aKey/entName = "
0445: + typClass + "/" + aKey + "/" + entName);
0446: return entName;
0447: }
0448:
0449: /**
0450: * Returns a name from the EntityNameFinderService, for a key and classname
0451: * @param className
0452: * @param aKey
0453: * @return String
0454: */
0455: public static String getEntityName(String className, String aKey) {
0456: String entName = "";
0457: Utility
0458: .logMessage(
0459: "DEBUG",
0460: "GroupsManagerXML.getEntityName(String,String): Retrieving entity for entityType: "
0461: + className + " key: " + aKey);
0462: try {
0463: entName = getEntityName(Class.forName(className), aKey);
0464: } catch (Exception e) {
0465: Utility.logMessage("ERROR",
0466: "GroupsManagerXML.getEntityName(String,String): ERROR retrieving entity "
0467: + e, e);
0468: }
0469: return entName;
0470: }
0471:
0472: /**
0473: * Returns a HashMap of entity types. These are the entity types that can be added
0474: * to a group. We determine this by retrieving all entity types from the EntityTypes
0475: * class and using the GroupService class to determine which types have a root
0476: * group.
0477: * @return HashMap
0478: */
0479: public static HashMap getEntityTypes() {
0480: HashMap entTypes = new HashMap(5);
0481: /* @todo can't determine size due to private methods */
0482: //HashMap entTypes = new HashMap(EntityTypes.singleton().getEntityTypesByType().size());
0483: String entName;
0484: String entClassName;
0485: Iterator entTypesItr = EntityTypes.singleton()
0486: .getAllEntityTypes();
0487: while (entTypesItr.hasNext()) {
0488: Class entType = (Class) entTypesItr.next();
0489: entClassName = entType.getName();
0490: //entName = entClassName.substring(entClassName.lastIndexOf('.') + 1);
0491: entName = EntityTypes.singleton()
0492: .getDescriptiveNameForType(entType);
0493: try {
0494: if (GroupService.getRootGroup(entType) != null) {
0495: //entTypes.put(entName, entClassName);
0496: entTypes.put(entName, entType);
0497: Utility.logMessage("DEBUG",
0498: "GroupsManagerXML::getEntityTypes Added : "
0499: + entName + " -- " + entClassName);
0500: } else {
0501: Utility.logMessage("DEBUG",
0502: "GroupsManagerXML::getEntityTypes Did NOT Add : "
0503: + entName + " -- " + entClassName);
0504: }
0505: } catch (Exception e) {
0506: // an exception means we do not want to add this entity to the list
0507: Utility
0508: .logMessage(
0509: "DEBUG",
0510: "GroupsManagerXML::getEntityTypes: "
0511: + entName
0512: + " -- "
0513: + entClassName
0514: + " does not have a root group.. NOT ADDED");
0515: }
0516: }
0517: return entTypes;
0518: }
0519:
0520: /**
0521: * Returns an element holding the entity types used in uPortal.
0522: * @param xmlDoc
0523: * @return Element
0524: */
0525: public static Element getEntityTypesXml(Document xmlDoc) {
0526: Element etRoot = xmlDoc.createElement("entityTypes");
0527: HashMap entTypes = getEntityTypes();
0528: Iterator entTypeKeys = entTypes.keySet().iterator();
0529: while (entTypeKeys.hasNext()) {
0530: Object key = entTypeKeys.next();
0531: //String entType = (String)entTypes.get(key);
0532: String entType = ((Class) entTypes.get(key)).getName();
0533: Element etElem = xmlDoc.createElement("entityType");
0534: etElem.setAttribute("name", (String) key);
0535: etElem.setAttribute("type", entType);
0536: etRoot.appendChild(etElem);
0537: }
0538: return etRoot;
0539: }
0540:
0541: /**
0542: * Returns an Element with the expanded attribute set to true from a
0543: * Document for a tagname and IGroupMember key. This could be used for
0544: * cloning elements that have already be expanded thereby avoiding the extra
0545: * time required to retrieve and create an element.
0546: * @param aDoc
0547: * @param tagname
0548: * @param key
0549: * @return Element
0550: */
0551: public static Element getExpandedElementForTagNameAndKey(
0552: Document aDoc, String tagname, String key) {
0553: java.util.Iterator nodeItr = getNodesByTagNameAndKey(aDoc,
0554: tagname, key);
0555: Element curElem = null;
0556: Element expElem = null;
0557: while (nodeItr.hasNext()) {
0558: curElem = (Element) nodeItr.next();
0559: if (curElem.getAttribute("expanded").equals("true")) {
0560: expElem = curElem;
0561: break;
0562: }
0563: }
0564: return expElem;
0565: }
0566:
0567: /**
0568: * Returns an Element for an IGroupMember. If an element is passed in,
0569: * it is acted upon (eg. expand the group), otherwise a new one is created.
0570: * @param gm
0571: * @param isContextExpanded
0572: * @param anElem
0573: * @param sd CGroupsManagerUnrestrictedSessionData
0574: * @return Element
0575: */
0576: public static Element getGroupMemberXml(IGroupMember gm,
0577: boolean isContextExpanded, Element anElem,
0578: CGroupsManagerUnrestrictedSessionData sd) {
0579: // search elements are nonPersistent and come in as a null group member.
0580: Document aDoc = sd.model;
0581: if (gm == null) {
0582: return null;
0583: }
0584: Element rootElem = anElem;
0585: String tagname = ENTITY_TAGNAME;
0586: if (gm.isGroup()) {
0587: tagname = GROUP_TAGNAME;
0588: rootElem = (rootElem != null ? rootElem : GroupsManagerXML
0589: .createElement(GROUP_TAGNAME, aDoc, false));
0590: rootElem.setAttribute("expanded", String
0591: .valueOf(isContextExpanded));
0592: }
0593: IGroupsManagerWrapper rap = getWrapper(tagname);
0594: if (rap != null) {
0595: rootElem = rap.getXml(gm, rootElem, sd);
0596: }
0597: return rootElem;
0598: }
0599:
0600: /**
0601: * Returns a new Document
0602: * @return Document
0603: */
0604: public static Document getNewDocument() {
0605: Document aDoc = null;
0606: Utility
0607: .logMessage("DEBUG",
0608: "GroupsManagerXML::getNewDocument(): About to get new Document");
0609: try {
0610: aDoc = DocumentBuilderFactory.newInstance()
0611: .newDocumentBuilder().newDocument();
0612: } catch (ParserConfigurationException pce) {
0613: Utility.logMessage("ERROR",
0614: "GroupsManagerXML::getNewDocument(): Unable to get new Document\n"
0615: + pce, pce);
0616: }
0617: return aDoc;
0618: }
0619:
0620: /**
0621: * Returns the next sequential identifier which is used to uniquely
0622: * identify an element. This identifier is held in the Element "id" attribute.
0623: * "0" is reserved for the Element holding the root group element.
0624: * @return String
0625: */
0626: public static synchronized String getNextUid() {
0627: // max size of int = (2 to the 32 minus 1) = 2147483647
0628: Utility.logMessage("DEBUG",
0629: "GroupsManagerXML::getNextUid(): Start");
0630: if (UID > 2147483600) {
0631: UID = 0;
0632: }
0633: return String.valueOf(++UID);
0634: }
0635:
0636: /**
0637: * Even though we know we will find a single element, we sometimes want
0638: * it returned in an iterator in order to streamline processing.
0639: * @param aDoc
0640: * @param id
0641: * @return iterator
0642: */
0643: public static java.util.Iterator getNodesById(Document aDoc,
0644: String id) {
0645: Collection nodes = new java.util.ArrayList();
0646: Element elem = getElementById(aDoc, id);
0647: nodes.add(elem);
0648: return nodes.iterator();
0649: }
0650:
0651: /**
0652: * Returns an iterator of Nodes for a Document for a tagname and IGroupMember key
0653: * @param aDoc
0654: * @param tagname
0655: * @param key
0656: * @return Iterator
0657: */
0658: public static java.util.Iterator getNodesByTagNameAndKey(
0659: Document aDoc, String tagname, String key) {
0660: int i;
0661: Collection nodes = new java.util.ArrayList();
0662: Element elem = null;
0663: org.w3c.dom.NodeList nList = aDoc.getElementsByTagName(tagname);
0664:
0665: for (i = 0; i < nList.getLength(); i++) {
0666: elem = (Element) nList.item(i);
0667: if (elem.getAttribute("key").equals(key)) {
0668: nodes.add(nList.item(i));
0669: }
0670: }
0671: Utility.logMessage("DEBUG",
0672: "GroupsManagerXML::getNodesByTagNameAndKey: Number of nodes found for tagname "
0673: + tagname + " and Key: " + key + " is: "
0674: + nodes.size());
0675: return nodes.iterator();
0676: }
0677:
0678: /**
0679: * Returns an iterator of Nodes for an Element for a tagname and IGroupMember key
0680: * @param anElem
0681: * @param tagname
0682: * @param key
0683: * @return Iterator
0684: */
0685: public static java.util.Iterator getNodesByTagNameAndKey(
0686: Element anElem, String tagname, String key) {
0687: int i;
0688: Collection nodes = new java.util.ArrayList();
0689: Element elem = null;
0690: org.w3c.dom.NodeList nList = anElem
0691: .getElementsByTagName(tagname);
0692:
0693: for (i = 0; i < nList.getLength(); i++) {
0694: elem = (Element) nList.item(i);
0695: if (elem.getAttribute("key").equals(key)) {
0696: nodes.add(nList.item(i));
0697: }
0698: }
0699: Utility.logMessage("DEBUG",
0700: "GroupsManagerXML::getNodesByTagNameAndKey: Number of nodes found for tagname "
0701: + tagname + " and Key: " + key + " is: "
0702: + nodes.size());
0703: return nodes.iterator();
0704: }
0705:
0706: /**
0707: * Returns an element for a permission.
0708: * @param xmlDoc
0709: * @param prmPrincipal
0710: * @param prmActivity
0711: * @param prmType
0712: * @param prmTarget
0713: * @return Element
0714: */
0715: public static Element getPermissionXml(Document xmlDoc,
0716: String prmPrincipal, String prmActivity, String prmType,
0717: String prmTarget) {
0718: Element prm = xmlDoc.createElement("permission");
0719: prm.setAttribute("principal", prmPrincipal);
0720: prm.setAttribute("activity", prmActivity);
0721: prm.setAttribute("type", prmType);
0722: prm.setAttribute("target", prmTarget);
0723: return prm;
0724: }
0725:
0726: /**
0727: * Returns a group member wrapper.
0728: * @param type
0729: * @return IGroupsManagerWrapper
0730: */
0731: public static IGroupsManagerWrapper getWrapper(String type) {
0732: String tagname = (type.equals(ENTITY_TAGNAME) || type
0733: .equals(ENTITY_CLASSNAME)) ? ENTITY_TAGNAME
0734: : GROUP_TAGNAME;
0735: IGroupsManagerWrapper rap = GroupsManagerWrapperFactory
0736: .get(tagname);
0737: return rap;
0738: }
0739:
0740: /**
0741: * Group elements that hold search results are non-persistent and should be treated differently.
0742: * For example, they do not have a "key" attribute so code that attempts to retreive
0743: * a GroupMember should not be attempted.
0744: * @param anElem Element
0745: * @return boolean
0746: */
0747: public static boolean isPersistentGroup(Element anElem) {
0748: boolean rval = true;
0749: if (anElem == null) {
0750: /* @todo this should be an error */
0751: Utility
0752: .logMessage("INFO",
0753: "GroupsManagerXML::isPersistentGroup(): anElem is null");
0754: }
0755: // Elements referencing non-groups (i.e. IEntities), search results, and the
0756: // document's root element are consider to hold information about non-persistent groups
0757: if (!Utility.areEqual(anElem.getNodeName(), GROUP_TAGNAME)
0758: || Utility.areEqual(anElem
0759: .getAttribute("searchResults"), "true")
0760: || anElem.getAttribute("id").equals("0")) {
0761: rval = false;
0762: }
0763: return rval;
0764: }
0765:
0766: /**
0767: * Updates all nodes for the same IEntityGroup with information about the IEntityGroup.
0768: * @param sd CGroupsManagerUnrestrictedSessionData
0769: * @param entGrp IEntityGroup
0770: */
0771: public static void refreshAllNodes(
0772: CGroupsManagerUnrestrictedSessionData sd,
0773: IEntityGroup entGrp) {
0774: Document model = sd.model;
0775: String updKey = entGrp.getKey();
0776: Node updNode;
0777: Element updElem;
0778: Utility
0779: .logMessage(
0780: "DEBUG",
0781: "GroupsManagerXML::refreshAllNodes(): About to refresh all nodes for IEntityGroup: "
0782: + updKey);
0783: Iterator updatedNodes = GroupsManagerXML
0784: .getNodesByTagNameAndKey(model, GROUP_TAGNAME, updKey);
0785: Utility.logMessage("DEBUG",
0786: "GroupsManagerXML::refreshAllNodes(): About to gather all elements for key: "
0787: + updKey);
0788: while (updatedNodes.hasNext()) {
0789: updNode = (Node) updatedNodes.next();
0790: updElem = (Element) updNode;
0791: refreshElement(updElem, entGrp);
0792: }
0793: return;
0794: }
0795:
0796: /**
0797: * Updates all nodes representing the same IEntityGroup that is represented by the
0798: * anElem, if the anElem is out of date with the IEntityGroup.
0799: * @param sd CGroupsManagerUnrestrictedSessionData
0800: * @param anElem Element
0801: */
0802: public static void refreshAllNodesIfRequired(
0803: CGroupsManagerUnrestrictedSessionData sd, Element anElem) {
0804: // A search element holds search results and should not be refreshed
0805: // because it is not persistent.
0806: if (!isPersistentGroup(anElem)) {
0807: return;
0808: }
0809: try {
0810: // refresh nodes if the anElem is out of date
0811: if (refreshRequired(anElem, null)) {
0812: Utility.logMessage("Debug",
0813: "GroupsManagerXML::refreshAllNodesIfRequired(): Element needs refreshing : "
0814: + anElem);
0815: refreshAllNodes(sd, retrieveGroup(anElem
0816: .getAttribute("key")));
0817: }
0818: } catch (Exception e) {
0819: Utility
0820: .logMessage(
0821: "INFO",
0822: "GroupsManagerXML::refreshAllNodesIfRequired(): "
0823: + "Unable to refresh all elements for IEntityGroup represented by element: "
0824: + anElem);
0825: Utility.logMessage("INFO", e.toString(), e);
0826: }
0827: return;
0828: }
0829:
0830: /**
0831: * Updates all nodes representing the same IEntityGroup that is represented by the
0832: * anElem, if the anElem is out of date with the IEntityGroup. Additionally, we
0833: * do the same for each child node (one level down at this time).
0834: * @param sd CGroupsManagerUnrestrictedSessionData
0835: * @param parentElem Element
0836: */
0837: public static void refreshAllNodesRecursivelyIfRequired(
0838: CGroupsManagerUnrestrictedSessionData sd, Element parentElem) {
0839: /* @todo not really recursive, we only go one level down, reconcile this
0840: * in code or by changing name */
0841: if (parentElem == null) {
0842: /* @todo this should be an error */
0843: Utility
0844: .logMessage("INFO",
0845: "GroupsManagerXML::refreshAllNodesRecursivelyIfRequired(): parentElem is null");
0846: return;
0847: }
0848: Element childElem;
0849: Node childNode;
0850: NodeList childNodes;
0851: String childType;
0852: boolean isParentElementExpanded = (Utility.areEqual(parentElem
0853: .getAttribute("expanded"), "true") ? true : false);
0854: refreshAllNodesIfRequired(sd, parentElem);
0855: if (isParentElementExpanded) {
0856: //String parentType = parentElem.getAttribute("type");
0857: Node parentNode = parentElem;
0858: childNodes = parentNode.getChildNodes();
0859: for (int i = 0; i < childNodes.getLength(); i++) {
0860: childNode = childNodes.item(i);
0861: childElem = (Element) childNode;
0862: childType = childElem.getAttribute("type");
0863: if (Utility.notEmpty(childType)) {
0864: refreshAllNodesIfRequired(sd, childElem);
0865: }
0866: }
0867: // Parent may have had children added or removed
0868: // The wrapper will do this for us.
0869: // Have to check for non persistent search element before doing retrieval
0870: expandGroupElementXML(parentElem, sd);
0871: }
0872: return;
0873: }
0874:
0875: /**
0876: * Updates an Element with information about the IEntityGroup.
0877: * @param updElem Element
0878: * @param entGrp IEntityGroup
0879: */
0880: public static void refreshElement(Element updElem,
0881: IEntityGroup entGrp) {
0882: // A search element holds search results and should not be refreshed
0883: // because it is not persistent.
0884: if (!isPersistentGroup(updElem)) {
0885: return;
0886: }
0887: IEntityGroup updEntGrp = (entGrp != null ? entGrp
0888: : retrieveGroup(updElem.getAttribute("key")));
0889: //Utility.logMessage("DEBUG", "GroupsManagerXML::refreshElement(): About to update xml for element id: " + updElem.getAttribute("id") + " Key: " + updElem.getAttribute("key"));
0890: Utility.printElement(updElem, "Element before update------");
0891: NodeList nList = updElem.getElementsByTagName("dc:title");
0892: if (nList.getLength() > 0) {
0893: Node titleNode = nList.item(0);
0894: titleNode.getFirstChild().setNodeValue(entGrp.getName());
0895: }
0896:
0897: nList = updElem.getElementsByTagName("dc:description");
0898: if (nList.getLength() > 0) {
0899: Node descNode = nList.item(0);
0900: descNode.getFirstChild().setNodeValue(
0901: entGrp.getDescription());
0902: }
0903:
0904: nList = updElem.getElementsByTagName("dc:creator");
0905: if (nList.getLength() > 0) {
0906: Node descNode = nList.item(0);
0907: String crtName = GroupsManagerXML.getEntityName(updEntGrp
0908: .getLeafType(), updEntGrp.getCreatorID());
0909: descNode.getFirstChild().setNodeValue(crtName);
0910: }
0911: Utility.printElement(updElem, "Element after update++++++");
0912: return;
0913: }
0914:
0915: /**
0916: * Updates an Element with information about the IEntityGroup.
0917: * @param chkElem Element
0918: * @param entGrp IEntityGroup
0919: * @return boolean
0920: *
0921: */
0922: public static boolean refreshRequired(Element chkElem,
0923: IEntityGroup entGrp) {
0924: // A search element holds search results and should not be refreshed
0925: // because it is not persistent.
0926: if (!isPersistentGroup(chkElem)) {
0927: return false;
0928: }
0929: IEntityGroup chkEntGrp = (entGrp != null ? entGrp
0930: : retrieveGroup(chkElem.getAttribute("key")));
0931: Utility
0932: .logMessage(
0933: "DEBUG",
0934: "GroupsManagerXML::refreshRequired(): About to check if element needs to be refreshed for Element ID: "
0935: + chkElem.getAttribute("id")
0936: + " Key: "
0937: + chkElem.getAttribute("key"));
0938: String elemValue = getElementValueForTagName(chkElem,
0939: "dc:title");
0940: if (!Utility.areEqual(elemValue, chkEntGrp.getName())) {
0941: Utility
0942: .logMessage("DEBUG",
0943: "GroupsManagerXML::refreshRequired(): Name has changed!!");
0944: return true;
0945: }
0946: elemValue = getElementValueForTagName(chkElem, "dc:description");
0947: if (!Utility.areEqual(elemValue, chkEntGrp.getDescription())) {
0948: Utility
0949: .logMessage("DEBUG",
0950: "GroupsManagerXML::refreshRequired(): Description has changed!!");
0951: return true;
0952: }
0953:
0954: return false;
0955: }
0956:
0957: /**
0958: * Returns an IEntity for the key.
0959: * @param aKey
0960: * @param aType
0961: * @return IEntity
0962: */
0963: public static IEntity retrieveEntity(String aKey, String aType) {
0964: IEntity ent = null;
0965: try {
0966: Class iEntityClass = Class.forName(aType);
0967: ent = GroupService.getEntity(aKey, iEntityClass);
0968: } catch (Exception e) {
0969: Utility.logMessage("ERROR",
0970: "EntityWrapper.retrieveEntity(): ERROR retrieving entity "
0971: + e, e);
0972: }
0973: return ent;
0974: }
0975:
0976: /**
0977: * Returns an IEntityGroup for the key.
0978: * @param aKey
0979: * @return IEntityGroup
0980: */
0981: public static IEntityGroup retrieveGroup(String aKey) {
0982: Utility.logMessage("DEBUG",
0983: "GroupsManagerXML::retrieveGroup(): About to search for Group: "
0984: + aKey);
0985: IEntityGroup grp = null;
0986: try {
0987: if (aKey != null) {
0988: grp = GroupService.findGroup(aKey);
0989: }
0990: } catch (Throwable th) {
0991: Utility.logMessage("ERROR",
0992: "GroupsManagerXML::retrieveGroup(): Could not retrieve Group Member ("
0993: + aKey + "): \n" + th, th);
0994: }
0995: return grp;
0996: }
0997:
0998: /**
0999: * Returns the IGroupMember represented by an Element
1000: * @param aDoc
1001: * @param id
1002: * @return IGroupMember
1003: */
1004: public static IGroupMember retrieveGroupMemberForElementId(
1005: Document aDoc, String id) {
1006: Element gmElem = getElementById(aDoc, id);
1007: IGroupMember gm;
1008:
1009: // A null is returned if the element is null OR if the element is for a group that
1010: // is non-persistent
1011: if (gmElem == null
1012: || (Utility.areEqual(gmElem.getNodeName(),
1013: GROUP_TAGNAME) && !isPersistentGroup(gmElem))) {
1014: Utility
1015: .logMessage(
1016: "INFO",
1017: "GroupsManagerXML::retrieveGroupMemberForElementId(): Unable to retrieve the element with id = "
1018: + id);
1019: return null;
1020: } else {
1021: Utility.logMessage("DEBUG",
1022: "GroupsManagerXML::retrieveGroupMemberForElementId(): The child type = "
1023: + gmElem.getTagName());
1024: }
1025: gm = retrieveGroupMemberForElement(gmElem);
1026: return gm;
1027: }
1028:
1029: /**
1030: * Returns the IGroupMember represented by an Element
1031: * @param gmElem
1032: * @return IGroupMember
1033: */
1034: public static IGroupMember retrieveGroupMemberForElement(
1035: Element gmElem) {
1036: IGroupMember gm;
1037: String gmKey = gmElem.getAttribute("key");
1038: Utility
1039: .logMessage(
1040: "DEBUG",
1041: "GroupsManagerXML::retrieveGroupMemberForElement(): About to retrieve group member ("
1042: + gmElem.getTagName()
1043: + " for key: "
1044: + gmKey);
1045: if (gmElem.getTagName().equals(GROUP_TAGNAME)) {
1046: gm = GroupsManagerXML.retrieveGroup(gmKey);
1047: } else {
1048: gm = GroupsManagerXML.retrieveEntity(gmKey, gmElem
1049: .getAttribute("type"));
1050: }
1051: return gm;
1052: }
1053:
1054: /**
1055: * Returns the xml tagname for a GroupMember
1056: * @param gm IGroupMember
1057: * @return String
1058: */
1059: public static String getTagName(IGroupMember gm) {
1060: String tagname = (gm.isGroup() ? GROUP_TAGNAME : ENTITY_TAGNAME);
1061: return tagname;
1062: }
1063:
1064: /**
1065: * Removes all elements with the tagname from an element
1066: * @param anElem Element
1067: * @param tagname String
1068: */
1069: public static void removeElementsForTagName(Element anElem,
1070: String tagname) {
1071: //Utility.logMessage("DEBUG", "GroupsManagerXML:removeElementForTagNameFromElement(): retrieve element for tagname: " + tagname);
1072: Utility.printElement(anElem, "BEFORE properties are removed.");
1073: NodeList nList = anElem.getElementsByTagName(tagname);
1074: /* getElementsByTagName(tagname) returns all elements in the tree with the specified
1075: tagname. We have to make sure that the one we are removing has anElem as the parent
1076: otherwise besides being wrong we get the following error:
1077: org.w3c.dom.DOMException: NOT_FOUND_ERR:
1078: An attempt is made to reference a node in a context where it does not exist.
1079: */
1080: if (nList.getLength() > 0) {
1081: for (int i = 0; i < nList.getLength(); i++) {
1082: if (nList.item(i).getParentNode() == anElem) {
1083: anElem.removeChild(nList.item(i));
1084: }
1085: }
1086: }
1087: //Utility.printElement(anElem, "AFTER properties are removed.");
1088: return;
1089: }
1090:
1091: /**
1092: * Removes all property elements for an IGroupMember and optionally clears the Entity Property cache.
1093: * @param model Element
1094: * @param gm IGroupMember
1095: * @param clearCache boolean
1096: */
1097: public static void removePropertyElements(Document model,
1098: IGroupMember gm, boolean clearCache) {
1099: Element curElem;
1100: java.util.Iterator nodeItr = getNodesByTagNameAndKey(model,
1101: getTagName(gm), gm.getKey());
1102: while (nodeItr.hasNext()) {
1103: curElem = (Element) nodeItr.next();
1104: removeElementsForTagName(curElem, PROPERTIES_TAGNAME);
1105: }
1106: if (clearCache) {
1107: clearPropertiesCache(gm);
1108: }
1109: }
1110:
1111: /**
1112: * Removes all EntityProperites for a GroupMember from the Entity Property cache.
1113: * @param gm IGroupMember
1114: */
1115: public static void clearPropertiesCache(IGroupMember gm) {
1116: EntityPropertyRegistry.instance().clearCache(
1117: gm.getUnderlyingEntityIdentifier());
1118: }
1119:
1120: }
|