001: /*
002: * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: */
005: package com.sun.portal.desktop.admin.mbeans.tasks;
006:
007: import java.util.Map;
008: import java.util.Set;
009: import java.util.Iterator;
010: import java.util.logging.Level;
011: import java.util.logging.Logger;
012:
013: import org.w3c.dom.Element;
014: import org.xml.sax.SAXParseException;
015:
016: import java.io.InputStream;
017: import java.io.StringReader;
018: import com.sun.portal.desktop.context.AdminDPContext;
019: import com.sun.portal.desktop.context.DPContext;
020:
021: import com.sun.portal.desktop.dp.DPError;
022: import com.sun.portal.desktop.dp.DPRoot;
023: import com.sun.portal.desktop.dp.DPNode;
024: import com.sun.portal.desktop.dp.DPProvider;
025: import com.sun.portal.desktop.dp.DPPropertyHolder;
026: import com.sun.portal.desktop.dp.DPContainerChannel;
027: import com.sun.portal.desktop.dp.DPChannel;
028: import com.sun.portal.desktop.dp.DPProperties;
029: import com.sun.portal.desktop.dp.DPCollection;
030: import com.sun.portal.desktop.dp.DPProperty;
031: import com.sun.portal.desktop.dp.DPCollection;
032: import com.sun.portal.desktop.dp.DPReferenceList;
033:
034: import com.sun.portal.desktop.dp.xml.XMLDPFactory;
035: import com.sun.portal.desktop.dp.xml.XMLDPTags;
036: import com.sun.portal.desktop.dp.xml.XMLDPCollection;
037: import com.sun.portal.desktop.dp.xml.XMLDPRoot;
038: import com.sun.portal.desktop.dp.xml.XMLDPNode;
039: import com.sun.portal.desktop.dp.xml.XMLDPPropertyHolder;
040: import com.sun.portal.desktop.dp.xml.XMLDPContainerChannel;
041: import com.sun.portal.desktop.dp.xml.XMLDPProperties;
042: import com.sun.portal.desktop.dp.xml.XMLDPReferenceList;
043:
044: import java.util.logging.Level;
045: import java.util.logging.Logger;
046:
047: public class DPAModify {
048:
049: private Logger logger;
050: // XML DP Factory
051: XMLDPFactory dpf = XMLDPFactory.getInstance();
052:
053: boolean verbose = false;
054:
055: public void process(AdminDPContext adc, String dn, boolean global,
056: String parent, boolean combine,
057: InputStream[] xmlByteStreams, boolean verbose,
058: boolean dryrun, Logger logger) throws DPAException {
059:
060: this .verbose = verbose;
061: this .logger = logger;
062:
063: if (verbose) {
064: logger.log(Level.INFO, "PSDT_CSPDAMT0023");
065: }
066:
067: // get document
068: String doc = null;
069: try {
070: if (!global) {
071: doc = adc.getDPDocument(dn);
072: } else {
073: doc = adc.getGlobalDPDocument();
074: }
075: } catch (Throwable ex) {
076: Object[] tokens = { global ? "<global>" : dn };
077: throw new DPAException("errorRetrieveDP", ex, tokens);
078: }
079: // build dproot
080: DPRoot dpr = null;
081: try {
082: if (doc != null && doc.length() > 0) {
083: dpr = dpf.createRoot(adc, doc);
084: }
085: } catch (Throwable ex) {
086: Object[] tokens = { global ? "<global>" : dn };
087: throw new DPAException("errorCreateDPRoot", ex, tokens);
088: }
089:
090: // iterate over xml input
091: for (int i = 0; i < xmlByteStreams.length; i++) {
092: dpr = doModify(adc, dn, global, parent, combine,
093: xmlByteStreams[i], verbose, dpr);
094: }
095:
096: if (verbose) {
097: logger.log(Level.INFO, "PSDT_CSPDAMT0024");
098: }
099:
100: //
101: // FIXME(susu): thre may be a better way to check for
102: // invalid xml.
103: //
104:
105: // check for invalid XML
106: String dpDoc = null;
107: try {
108: //
109: // set dirty to false before writing out.
110: // not doing this will cause "dirty=true" attribute to
111: // be added which will then cause validation error.
112: //
113: if (dpr.isDirty()) {
114: dpr.setDirty(false);
115: }
116: dpDoc = dpr.toString();
117: dpf.createRoot(adc, dpDoc);
118: } catch (DPError de) {
119: Throwable wrapped = de.getCause();
120: if (wrapped != null && wrapped instanceof SAXParseException) {
121: SAXParseException spe = (SAXParseException) wrapped;
122: int linenum = spe.getLineNumber();
123: Object[] tokens = { DPAUtil.getLines(new StringReader(
124: dpDoc), linenum) };
125: throw new DPAException("errorInvalidXMLText", de,
126: tokens);
127: }
128: } catch (Throwable ex) {
129: throw new DPAException("errorInvalidXML", ex);
130: }
131:
132: // write out changed dp only if dryrun is off
133: if (!dryrun) {
134: if (verbose) {
135: logger.log(Level.INFO, "PSDT_CSPDAMT0025");
136: }
137: try {
138: StringBuffer sb = new StringBuffer(256);
139: dpr.toXML(sb, 0);
140: if (!global) {
141: adc.storeDPDocument(dn, sb.toString());
142: } else {
143: adc.storeGlobalDPDocument(sb.toString());
144: }
145: } catch (Throwable ex) {
146: throw new DPAException("errorStoreDP", ex);
147: }
148: }
149: }
150:
151: private DPRoot doModify(AdminDPContext adc, String dn,
152: boolean global, String parent, boolean combine,
153: InputStream xmlByteStream, boolean verbose, DPRoot dpr)
154: throws DPAException {
155:
156: Element element = DPAUtil.getElement(adc, xmlByteStream);
157: String tag = element.getTagName();
158:
159: if (verbose) {
160: Object[] tokens = { tag };
161: logger.log(Level.INFO, "PSDT_CSPDAMT0026", tokens);
162: }
163:
164: // combine flag is only supported for certain tags
165: if (!tag.equals(XMLDPTags.DISPLAYPROFILE_TAG)
166: && !tag.equals(XMLDPTags.CHANNEL_TAG)
167: && !tag.equals(XMLDPTags.CONTAINER_TAG)
168: && !tag.equals(XMLDPTags.PROPERTIES_TAG)
169: && !tag.equals(XMLDPTags.COLLECTION_TAG)
170: && !tag.equals(XMLDPTags.CONDITIONALPROPERTIES_TAG)
171: && !tag.equals(XMLDPTags.LOCALE_TAG)
172: && !tag.equals(XMLDPTags.AVAILABLE_TAG)
173: && !tag.equals(XMLDPTags.SELECTED_TAG)) {
174:
175: if (combine) {
176: Object[] tokens = { tag };
177: throw new DPAException("errorCombineNotSupported",
178: tokens);
179: }
180: }
181:
182: // modifying dp
183: if (tag.equals(XMLDPTags.DISPLAYPROFILE_TAG)) {
184:
185: if (parent != null) {
186: Object[] tokens = { parent };
187: throw new DPAException("errorCannotHaveParent", tokens);
188: }
189: dpr = doModifyDP(adc, dn, global, combine, element, dpr);
190:
191: } else {
192:
193: // modify dp obj.
194: if (tag.equals(XMLDPTags.CHANNEL_TAG)
195: || tag.equals(XMLDPTags.CONTAINER_TAG)) {
196:
197: dpr = doModifyChannel(adc, dpr, parent, combine,
198: element);
199:
200: } else if (tag.equals(XMLDPTags.PROVIDER_TAG)) {
201:
202: if (parent != null) {
203: Object[] tokens = { parent };
204: throw new DPAException(
205: "errorProviderCannotHaveParent", tokens);
206: }
207: dpr = doModifyProvider(adc, dpr, element);
208:
209: } else if (tag.equals(XMLDPTags.STRING_TAG)
210: || tag.equals(XMLDPTags.BOOLEAN_TAG)
211: || tag.equals(XMLDPTags.INTEGER_TAG)
212: || tag.equals(XMLDPTags.COLLECTION_TAG)
213: || tag.equals(XMLDPTags.CONDITIONALPROPERTIES_TAG)
214: || tag.equals(XMLDPTags.LOCALE_TAG)) {
215:
216: dpr = doModifyProperty(adc, dpr, parent, combine,
217: element);
218:
219: } else if (tag.equals(XMLDPTags.PROPERTIES_TAG)) {
220:
221: dpr = doModifyProperties(adc, dpr, parent, combine,
222: element);
223:
224: } else if (tag.equals(XMLDPTags.AVAILABLE_TAG)
225: || tag.equals(XMLDPTags.SELECTED_TAG)) {
226:
227: if (parent == null) {
228: throw new DPAException("errorParentUnspecified");
229: }
230: dpr = doModifyList(adc, dpr, parent, combine, element,
231: tag);
232:
233: } else {
234: Object[] tokens = { tag };
235: throw new DPAException("errorUnsupportedTag", tokens);
236: }
237: }
238:
239: return dpr;
240: }
241:
242: private DPRoot doModifyDP(AdminDPContext adc, String dn,
243: boolean global, boolean combine, Element element, DPRoot dpr)
244: throws DPAException {
245:
246: if (verbose) {
247: Object[] tokens = { global ? DPAUtil
248: .getLocalizedString("msgGlobal") : dn };
249: logger.log(Level.INFO, "PSDT_CSPDAMT0027", tokens);
250: }
251:
252: StringBuffer doc = null;
253: DPRoot newDpr = null;
254: try {
255: newDpr = dpf.getRoot(adc, element);
256: } catch (Throwable ex) {
257: throw new DPAException("errorInvalidXML", ex);
258: }
259:
260: if (combine) {
261: //
262: // first, check to make sure that the DP is a valid XML
263: //
264: if (verbose) {
265: logger.log(Level.INFO, "PSDT_CSPDAMT0028");
266: }
267:
268: //
269: // FIXME(susu): thre may be a better way to check for
270: // invalid xml.
271: //
272:
273: String dpDoc = null;
274: try {
275: dpDoc = newDpr.toString();
276: dpf.createRoot(adc, dpDoc);
277: } catch (DPError de) {
278: Throwable wrapped = de.getCause();
279: if (wrapped != null
280: && wrapped instanceof SAXParseException) {
281: SAXParseException spe = (SAXParseException) wrapped;
282: int linenum = spe.getLineNumber();
283: Object[] tokens = { DPAUtil.getLines(
284: new StringReader(dpDoc), linenum) };
285: throw new DPAException("errorInvalidXMLText", de,
286: tokens);
287: }
288: } catch (Throwable ex) {
289: throw new DPAException("errorInvalidXML", ex);
290: }
291:
292: if (dpr != null) {
293: DPAUtil.combineRoots(dpr, newDpr);
294: newDpr = dpr;
295: }
296: // else {
297: // original doc was empty
298: // just replace the entire content with the new dp.
299: // }
300: }
301:
302: return newDpr;
303: }
304:
305: private DPRoot doModifyChannel(DPContext adc, DPRoot dpr,
306: String parent, boolean combine, Element element)
307: throws DPAException {
308:
309: if (verbose) {
310: Object[] tokens = {
311: element.getAttribute("name"),
312: (parent == null ? DPAUtil
313: .getLocalizedString("msgRoot") : parent) };
314:
315: logger.log(Level.INFO, "PSDT_CSPDAMT0029", tokens);
316: }
317:
318: DPNode node = null;
319: try {
320: if (parent == null) {
321: node = dpr;
322: } else {
323: if (verbose) {
324: Object[] tokens = { parent };
325: logger.log(Level.INFO, "PSDT_CSPDAMT0030", tokens);
326: }
327: XMLDPRoot xdpr = (XMLDPRoot) dpr;
328: node = xdpr.getChannelFromThis(parent);
329: }
330: } catch (Throwable ex) {
331: Object[] tokens = { parent == null ? "<root>" : parent };
332: throw new DPAException("errorFindParent", ex, tokens);
333: }
334:
335: if (node == null) {
336: Object[] tokens = { parent == null ? "<root>" : parent };
337: throw new DPAException("errorFindParent", tokens);
338: }
339:
340: if (verbose) {
341: logger.log(Level.INFO, "PSDT_CSPDAMT0031");
342: }
343: DPChannel ch = null;
344: try {
345: ch = dpf.getChannel(adc, dpr, element);
346: } catch (Throwable ex) {
347: throw new DPAException("errorCreateDPChannel", ex);
348: }
349:
350: if (verbose) {
351: Object[] tokens = { parent == null ? "<root>" : parent };
352: logger.log(Level.INFO, "PSDT_CSPDAMT0032", tokens);
353: }
354: DPChannel och = null;
355: try {
356: XMLDPNode xnode = (XMLDPNode) node;
357: och = xnode.getChannelFromThis(ch.getName());
358: } catch (Throwable ex) {
359: Object[] tokens = { (parent == null ? "<root>" : parent),
360: ch.getName() };
361: throw new DPAException("errorLookupChannel", ex, tokens);
362: }
363:
364: if (och == null) {
365: Object[] tokens = { (parent == null ? "<root>" : parent),
366: ch.getName() };
367: throw new DPAException("errorFindChannel", tokens);
368: }
369:
370: try {
371: if (combine) {
372: DPAUtil.combineChannels(och, ch);
373: } else {
374: node.removeChannel(ch.getName());
375: node.addChannel(ch);
376: }
377: } catch (Throwable ex) {
378: Object[] tokens = { (parent == null ? "<root>" : parent),
379: ch.getName() };
380: throw new DPAException("errorModifyChannel", ex, tokens);
381: }
382:
383: return dpr;
384: }
385:
386: private DPRoot doModifyProvider(DPContext adc, DPRoot dpr,
387: Element element) throws DPAException {
388:
389: if (verbose) {
390: Object[] tokens = { element.getAttribute("name") };
391: logger.log(Level.INFO, "PSDT_CSPDAMT0033", tokens);
392: }
393:
394: if (verbose) {
395: logger.log(Level.INFO, "PSDT_CSPDAMT0034");
396: }
397: DPProvider p = null;
398: try {
399: p = dpf.getProvider(adc, dpr, element);
400: } catch (Throwable ex) {
401: throw new DPAException("errorCreateDPProvider", ex);
402: }
403:
404: if (verbose) {
405: logger.log(Level.INFO, "PSDT_CSPDAMT0035");
406: }
407: boolean exists = false;
408: try {
409: XMLDPRoot xdpr = (XMLDPRoot) dpr;
410: exists = (xdpr.getProviderFromThis(p.getName()) != null);
411: } catch (Throwable ex) {
412: Object[] tokens = { p.getName() };
413: throw new DPAException("errorLookupProvider", ex, tokens);
414: }
415: if (!exists) {
416: Object[] tokens = { p.getName() };
417: throw new DPAException("errorFindProvider", tokens);
418: }
419:
420: try {
421: dpr.removeProvider(p.getName());
422: dpr.addProvider(p);
423: } catch (Throwable ex) {
424: Object[] tokens = { p.getName() };
425: throw new DPAException("errorModifyProvider", ex, tokens);
426: }
427:
428: return dpr;
429: }
430:
431: private DPRoot doModifyProperties(DPContext adc, DPRoot dpr,
432: String parent, boolean combine, Element element)
433: throws DPAException {
434:
435: if (verbose) {
436: Object[] tokens = {
437: element.getAttribute("name"),
438: (parent == null ? DPAUtil
439: .getLocalizedString("msgRoot") : parent) };
440: logger.log(Level.INFO, "PSDT_CSPDAMT0036", tokens);
441: }
442:
443: DPPropertyHolder ph = null;
444: try {
445: if (parent == null) {
446: ph = dpr;
447: } else {
448: if (verbose) {
449: Object[] tokens = { parent };
450: logger.log(Level.INFO, "PSDT_CSPDAMT0037", tokens);
451: }
452: XMLDPRoot xdpr = (XMLDPRoot) dpr;
453: ph = xdpr.getChannelFromThis(parent);
454: if (ph == null) {
455: ph = xdpr.getProviderFromThis(parent);
456: }
457: }
458: } catch (Throwable ex) {
459: Object[] tokens = { parent == null ? "<root>" : parent };
460: throw new DPAException("errorFindParent", ex, tokens);
461: }
462:
463: if (ph == null) {
464: Object[] tokens = { parent == null ? "<root>" : parent };
465: throw new DPAException("errorFindParent", tokens);
466: }
467:
468: if (verbose) {
469: logger.log(Level.INFO, "PSDT_CSPDAMT0038");
470: }
471: DPCollection c = null;
472: DPProperties op = null;
473: try {
474: XMLDPPropertyHolder xph = (XMLDPPropertyHolder) ph;
475: op = xph.getPropertiesFromThis();
476:
477: //
478: // treat what is actually a Properties element as
479: // a Collection. this is to avoid the
480: // look in the provider, look in parent node
481: // semantics that are include in the
482: // XMLDPProperties class
483: //
484: c = dpf.getCollectionProperty(adc, dpr, element);
485: } catch (Throwable ex) {
486: throw new DPAException("errorCreateDPProperties", ex);
487: }
488:
489: try {
490: if (combine) {
491: DPAUtil.combineProperties(op, c);
492: } else {
493: op.removeAll();
494:
495: //
496: // FIXME(susu): is there a quicker way to do this
497: // than iterating one by one?
498: //
499: XMLDPCollection xc = (XMLDPCollection) c;
500: Set names = xc.getNamesFromThis();
501: for (Iterator i = names.iterator(); i.hasNext();) {
502: op.add(xc.getFromThis((String) i.next()));
503: }
504:
505: //
506: // reset merge attributes
507: //
508: XMLDPCollection xmlC = (XMLDPCollection) c;
509: Element e = xmlC.getElement();
510: op.setMergeType(c.getMergeType());
511: op.setLock(xmlC.isLockedElement(e));
512: op.setPropagate(xmlC.isPropagateElement(e));
513: op.setAdvanced(xmlC.isAdvancedElement(e));
514: }
515: } catch (Throwable ex) {
516: Object[] tokens = { parent == null ? "<root>" : parent };
517: throw new DPAException("errorModifyProperties", ex, tokens);
518: }
519:
520: return dpr;
521: }
522:
523: private DPRoot doModifyProperty(DPContext adc, DPRoot dpr,
524: String parent, boolean combine, Element element)
525: throws DPAException {
526:
527: if (verbose) {
528: Object[] tokens = {
529: element.getAttribute("name"),
530: (parent == null ? DPAUtil
531: .getLocalizedString("msgRoot") : parent) };
532: logger.log(Level.INFO, "PSDT_CSPDAMT0039", tokens);
533: }
534:
535: DPPropertyHolder ph = null;
536: try {
537: if (parent == null) {
538: ph = dpr;
539: } else {
540: if (verbose) {
541: Object[] tokens = { parent };
542: logger.log(Level.INFO, "PSDT_CSPDAMT0040", tokens);
543: }
544: XMLDPRoot xdpr = (XMLDPRoot) dpr;
545: ph = xdpr.getChannelFromThis(parent);
546: if (ph == null) {
547: ph = xdpr.getProviderFromThis(parent);
548: }
549: }
550: } catch (Throwable ex) {
551: Object[] tokens = { parent == null ? "<root>" : parent };
552: throw new DPAException("errorFindParent", ex, tokens);
553: }
554:
555: if (ph == null) {
556: Object[] tokens = { parent == null ? "<root>" : parent };
557: throw new DPAException("errorFindParent", tokens);
558: }
559:
560: if (verbose) {
561: logger.log(Level.INFO, "PSDT_CSPDAMT0041");
562: }
563: DPProperty p = null;
564: try {
565: p = dpf.getProperty(adc, dpr, element);
566: } catch (Throwable ex) {
567: throw new DPAException("errorCreateDPProperty", ex);
568: }
569:
570: if (verbose) {
571: Object[] tokens = { parent == null ? DPAUtil
572: .getLocalizedString("msgRoot") : parent };
573: logger.log(Level.INFO, "PSDT_CSPDAMT0042", tokens);
574: }
575: DPProperties props = null;
576: boolean exists = false;
577: try {
578: XMLDPPropertyHolder xph = (XMLDPPropertyHolder) ph;
579: props = xph.getPropertiesFromThis();
580: XMLDPProperties xprops = (XMLDPProperties) props;
581: exists = (xprops.getFromThis(p.getName()) != null);
582: } catch (Throwable ex) {
583: Object[] tokens = { (parent == null ? "<root>" : parent),
584: p.getName() };
585: throw new DPAException("PSDT_CSPDAMT0043", ex, tokens);
586: }
587:
588: if (!exists) {
589: Object[] tokens = { (parent == null ? "<root>" : parent),
590: p.getName() };
591: throw new DPAException("errorFindProperty", tokens);
592: }
593:
594: try {
595: if (combine) {
596: DPCollection c = (DPCollection) p;
597: XMLDPProperties xprops = (XMLDPProperties) props;
598: DPCollection oc = (DPCollection) xprops.getFromThis(c
599: .getName());
600: DPAUtil.combineProperties(oc, c);
601: } else {
602: props.remove(p.getName());
603: props.add(p);
604: }
605: } catch (Throwable ex) {
606: Object[] tokens = { p };
607: throw new DPAException("errorModifyProperty", ex, tokens);
608: }
609:
610: return dpr;
611: }
612:
613: private DPRoot doModifyList(DPContext adc, DPRoot dpr,
614: String parent, boolean combine, Element element, String tag)
615: throws DPAException {
616:
617: if (verbose) {
618: Object[] tokens = { tag, parent };
619: logger.log(Level.INFO, "PSDT_CSPDAMT0044", tokens);
620: }
621: DPNode node = null;
622: try {
623: if (parent == null) {
624: node = dpr;
625: } else {
626: if (verbose) {
627: Object[] tokens = { parent };
628: logger.log(Level.INFO, "PSDT_CSPDAMT0045", tokens);
629: }
630: XMLDPRoot xdpr = (XMLDPRoot) dpr;
631: node = xdpr.getChannelFromThis(parent);
632: }
633: } catch (Throwable ex) {
634: Object[] tokens = { parent == null ? "<root>" : parent };
635: throw new DPAException("errorFindParent", ex, tokens);
636: }
637:
638: if (node == null) {
639: Object[] tokens = { parent == null ? "<root>" : parent };
640: throw new DPAException("errorFindParent", tokens);
641: }
642:
643: if (!(node instanceof DPContainerChannel)) {
644: Object[] tokens = { parent == null ? "<root>" : parent };
645: throw new DPAException("errorParentNotCotainer", tokens);
646: }
647:
648: DPContainerChannel cc = (DPContainerChannel) node;
649: DPReferenceList orl = null;
650: try {
651: XMLDPContainerChannel xcc = (XMLDPContainerChannel) cc;
652: if (tag.equals(XMLDPTags.AVAILABLE_TAG)) {
653: orl = xcc.getAvailableFromThis();
654: } else if (tag.equals(XMLDPTags.SELECTED_TAG)) {
655: orl = xcc.getSelectedFromThis();
656: }
657: } catch (Throwable ex) {
658: Object[] tokens = { tag,
659: (parent == null ? "<root>" : parent) };
660: throw new DPAException("errorLookupDPList", ex, tokens);
661: }
662:
663: if (verbose) {
664: Object[] tokens = { tag };
665: logger.log(Level.INFO, "PSDT_CSPDAMT0046", tokens);
666: }
667: DPReferenceList rl = null;
668: try {
669: if (tag.equals(XMLDPTags.AVAILABLE_TAG)) {
670: rl = dpf.getAvailable(adc, dpr, element);
671: } else if (tag.equals(XMLDPTags.SELECTED_TAG)) {
672: rl = dpf.getSelected(adc, dpr, element);
673: }
674: } catch (Throwable ex) {
675: Object[] tokens = { tag };
676: throw new DPAException("errorCreateDPList", ex, tokens);
677: }
678:
679: try {
680: if (combine) {
681: DPAUtil.combineLists(orl, rl);
682: } else {
683: orl.removeAll();
684:
685: //
686: // FIXME(susu): is there a quicker way to do this
687: // than iterating one by one?
688: //
689: XMLDPReferenceList xrl = (XMLDPReferenceList) rl;
690: Set names = xrl.getNamesFromThis();
691: for (Iterator i = names.iterator(); i.hasNext();) {
692: orl.add(xrl.getFromThis((String) i.next()));
693: }
694: //
695: // reset merge attributes
696: //
697: XMLDPReferenceList xmlRl = (XMLDPReferenceList) rl;
698: Element e = xmlRl.getElement();
699: orl.setMergeType(rl.getMergeType());
700: orl.setLock(xmlRl.isLockedElement(e));
701: orl.setAdvanced(xmlRl.isAdvancedElement(e));
702: }
703: } catch (Throwable ex) {
704: Object[] tokens = { tag, parent };
705: throw new DPAException("errorModifyDPList", ex, tokens);
706: }
707: return dpr;
708: }
709:
710: }
|