001: /* Copyright 2005 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.layout.dlm;
007:
008: import org.apache.commons.logging.Log;
009: import org.apache.commons.logging.LogFactory;
010: import org.jasig.portal.PortalException;
011: import org.w3c.dom.Document;
012: import org.w3c.dom.Element;
013: import org.w3c.dom.NodeList;
014:
015: /** Performs merging of PLF into ILF for DLM.
016: * @version $Revision: 36683 $ $Date: 2006-08-23 15:08:00 -0700 (Wed, 23 Aug 2006) $
017: * @since uPortal 2.5
018: */
019: public class PLFIntegrator {
020: public static final String RCS_ID = "@(#) $Header$";
021: private static Log LOG = LogFactory.getLog(PLFIntegrator.class);
022:
023: /**
024: */
025: public static void mergePLFintoILF(Document plf, Document ilf,
026: IntegrationResult result) throws PortalException {
027: // we want to use the root folders located as the single child of
028: // the layout elements which are the document elements.
029: Element plfLayout = plf.getDocumentElement();
030: Element plfRoot = (Element) plfLayout.getFirstChild();
031: Element ilfLayout = ilf.getDocumentElement();
032: Element ilfRoot = (Element) ilfLayout.getFirstChild();
033:
034: DeleteManager.applyAndUpdateDeleteSet(plf, ilf, result);
035: ParameterEditManager
036: .applyAndUpdateParmEditSet(plf, ilf, result);
037:
038: if (null == plfRoot) {
039: throw new RuntimeException(
040: "The PLF layout root element is missing, so it appears "
041: + "that the database has been corrupted.");
042: }
043:
044: applyChildChanges(plfRoot, ilfRoot, result);
045: }
046:
047: private static void applyChildChanges(Element plfParent,
048: Element ilfParent, IntegrationResult result)
049: throws PortalException {
050: Element positions = null;
051: Element node = (Element) plfParent.getFirstChild();
052:
053: while (node != null) {
054: Element nextNode = (Element) node.getNextSibling();
055:
056: if (node.getNodeName().equals("folder"))
057: mergeFolder(node, plfParent, ilfParent, result);
058: else if (node.getNodeName().equals(
059: Constants.ELM_POSITION_SET))
060: positions = node;
061: else if (node.getNodeName().equals("channel"))
062: mergeChannel(node, plfParent, ilfParent, result);
063: node = nextNode;
064: }
065:
066: if (positions != null) {
067: IntegrationResult posResult = new IntegrationResult();
068: if (LOG.isInfoEnabled())
069: LOG.info("applying positions");
070: PositionManager.applyPositions(ilfParent, positions,
071: posResult);
072: if (posResult.changedILF == false) {
073: if (LOG.isInfoEnabled())
074: LOG.info("removing positionSet");
075: plfParent.removeChild(positions);
076: result.changedPLF = true;
077: } else {
078: result.changedILF = true;
079: if (posResult.changedPLF)
080: result.changedPLF = true;
081: }
082: }
083: }
084:
085: private static void mergeChannel(Element plfChild,
086: Element plfParent, Element ilfParent,
087: IntegrationResult result) {
088: String id = plfChild.getAttribute(Constants.ATT_ID);
089:
090: if (id.startsWith(Constants.FRAGMENT_ID_USER_PREFIX)) {
091: // this should never happen. Moves of an incorporated channel
092: // should be indicated via the position set of the parent
093: } else // plf channel
094: {
095: if (LOG.isInfoEnabled())
096: LOG.info("merging into ilf channel " + id);
097:
098: if (ilfParent.getAttribute(Constants.ATT_ADD_CHILD_ALLOWED)
099: .equals("false")) {
100: if (LOG.isInfoEnabled())
101: LOG
102: .info("removing from plf disallowed add of channel "
103: + id);
104: plfParent.removeChild(plfChild);
105: result.changedPLF = true;
106: } else {
107: appendChild(plfChild, ilfParent, true);
108: result.changedILF = true;
109: }
110: }
111: }
112:
113: private static void mergeFolder(Element plfChild,
114: Element plfParent, Element ilfParent,
115: IntegrationResult result) throws PortalException {
116: String id = plfChild.getAttribute(Constants.ATT_ID);
117:
118: if (id.startsWith(Constants.FRAGMENT_ID_USER_PREFIX)) {
119: // incorporated folder - if a copy of an inc'd folder is in the
120: // plf it is because either it has attribute edits or there are
121: // nested child changes to be applied. It does not imply movement.
122: // That is accomplished by the position set. So see if it still
123: // exists in the ilf for applying changes
124:
125: Document ilf = ilfParent.getOwnerDocument();
126: Element original = ilf.getElementById(id);
127:
128: if (original == null) {
129: // not there anymore, discard from plf
130: plfParent.removeChild(plfChild);
131: result.changedPLF = true;
132: return;
133: }
134:
135: // found it, apply changes and see if they had any affect
136: boolean attributeChanged = false;
137: IntegrationResult childChanges = new IntegrationResult();
138:
139: attributeChanged = EditManager.applyEditSet(plfChild,
140: original);
141: applyChildChanges(plfChild, original, childChanges);
142:
143: if (attributeChanged == false
144: && childChanges.changedILF == false) {
145: // no changes were used so remove this guy from plf.
146: plfParent.removeChild(plfChild);
147: result.changedPLF = true;
148: } else
149: result.changedILF = true;
150: // need to pass on up whether PLF changed in called methods
151: if (childChanges.changedPLF)
152: result.changedPLF = true;
153: } else {
154: // plf folder - the real node. What is being portrayed in this
155: // case is a plf node that is supposed to be added into the ilf
156: // parent
157:
158: if (ilfParent.getAttribute(Constants.ATT_ADD_CHILD_ALLOWED)
159: .equals("false")) {
160: // nope, delete directive from plf
161: if (LOG.isInfoEnabled())
162: LOG.info("removing folder from plf " + id);
163: plfParent.removeChild(plfChild);
164: result.changedPLF = true;
165: return;
166: }
167: Element ilfChild = appendChild(plfChild, ilfParent, false);
168: result.changedILF = true;
169:
170: IntegrationResult childChanges = new IntegrationResult();
171: applyChildChanges(plfChild, ilfChild, childChanges);
172:
173: if (childChanges.changedPLF)
174: result.changedPLF = true;
175: }
176: }
177:
178: /**
179: This method copies a plf node and any of its children into the passed
180: in compViewParent.
181: */
182: static Element appendChild(Element plfChild, Element parent,
183: boolean copyChildren) {
184: Document document = parent.getOwnerDocument();
185: Element copy = (Element) document.importNode(plfChild, false);
186: parent.appendChild(copy);
187:
188: // set the identifier for the doc if warrented
189: String id = copy.getAttribute(Constants.ATT_ID);
190: if (id != null && !id.equals(""))
191: copy.setIdAttribute(Constants.ATT_ID, true);
192:
193: if (copyChildren) {
194: NodeList children = plfChild.getChildNodes();
195: for (int i = 0; i < children.getLength(); i++) {
196: if (children.item(i) instanceof Element)
197: appendChild((Element) children.item(i), copy, true);
198: }
199: }
200: return copy;
201: }
202:
203: }
|