KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > webapps > portal > components > PortalManagerImpl


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.webapps.portal.components;
17
18 import java.io.IOException JavaDoc;
19 import java.util.ArrayList JavaDoc;
20 import java.util.Enumeration JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import org.apache.avalon.excalibur.pool.Recyclable;
27 import org.apache.avalon.framework.activity.Disposable;
28 import org.apache.avalon.framework.component.Component;
29 import org.apache.avalon.framework.component.ComponentException;
30 import org.apache.avalon.framework.component.ComponentManager;
31 import org.apache.avalon.framework.component.Composable;
32 import org.apache.avalon.framework.component.Recomposable;
33 import org.apache.avalon.framework.configuration.Configuration;
34 import org.apache.avalon.framework.configuration.ConfigurationException;
35 import org.apache.avalon.framework.context.Context;
36 import org.apache.avalon.framework.context.ContextException;
37 import org.apache.avalon.framework.context.Contextualizable;
38 import org.apache.avalon.framework.logger.AbstractLogEnabled;
39 import org.apache.cocoon.ProcessingException;
40 import org.apache.cocoon.components.ContextHelper;
41 import org.apache.cocoon.components.sax.XMLDeserializer;
42 import org.apache.cocoon.components.source.SourceUtil;
43 import org.apache.cocoon.environment.CocoonRunnable;
44 import org.apache.cocoon.environment.Redirector;
45 import org.apache.cocoon.environment.Request;
46 import org.apache.cocoon.environment.Response;
47 import org.apache.cocoon.environment.Session;
48 import org.apache.cocoon.webapps.authentication.AuthenticationManager;
49 import org.apache.cocoon.webapps.authentication.user.RequestState;
50 import org.apache.cocoon.webapps.portal.PortalConstants;
51 import org.apache.cocoon.webapps.session.ContextManager;
52 import org.apache.cocoon.webapps.session.MediaManager;
53 import org.apache.cocoon.webapps.session.SessionManager;
54 import org.apache.cocoon.webapps.session.TransactionManager;
55 import org.apache.cocoon.webapps.session.context.SessionContext;
56 import org.apache.cocoon.webapps.session.xml.XMLUtil;
57 import org.apache.cocoon.xml.IncludeXMLConsumer;
58 import org.apache.cocoon.xml.XMLConsumer;
59 import org.apache.cocoon.xml.XMLUtils;
60 import org.apache.cocoon.xml.dom.DOMUtil;
61 import org.apache.excalibur.source.Source;
62 import org.apache.excalibur.source.SourceException;
63 import org.apache.excalibur.source.SourceParameters;
64 import org.apache.excalibur.source.SourceResolver;
65 import org.apache.excalibur.store.Store;
66 import org.apache.excalibur.xml.xpath.XPathProcessor;
67 import org.w3c.dom.Document JavaDoc;
68 import org.w3c.dom.DocumentFragment JavaDoc;
69 import org.w3c.dom.Element JavaDoc;
70 import org.w3c.dom.NamedNodeMap JavaDoc;
71 import org.w3c.dom.Node JavaDoc;
72 import org.w3c.dom.NodeList JavaDoc;
73 import org.w3c.dom.Text JavaDoc;
74 import org.xml.sax.Attributes JavaDoc;
75 import org.xml.sax.SAXException JavaDoc;
76 import org.xml.sax.helpers.AttributesImpl JavaDoc;
77
78 /**
79  * This is the basis portal component
80  *
81  * @author <a HREF="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
82  * @version CVS $Id: PortalManagerImpl.java 189932 2005-06-10 09:33:14Z sylvain $
83 */

84 public final class PortalManagerImpl
85 extends AbstractLogEnabled
86 implements Disposable, Composable, Recomposable, Recyclable, Contextualizable, Component, PortalManager {
87
88     /** The cache (store) for the profiles */
89     private Store profileStore;
90
91     /** The authenticationManager */
92     private AuthenticationManager authenticationManager;
93
94     /** The media manager */
95     private MediaManager mediaManager;
96
97     /** The XPath Processor */
98     private XPathProcessor xpathProcessor;
99
100     /** The session manager */
101     private SessionManager sessionManager;
102
103     /** The Context manager */
104     private ContextManager contextManager;
105
106     /** The transaction manager */
107     private TransactionManager transactionManager;
108
109     /** The component manager */
110     protected ComponentManager manager;
111
112     /** The current source resolver */
113     protected SourceResolver resolver;
114
115     /** The context */
116     protected Context componentContext;
117
118     /** Are we already setup for this request? */
119     protected boolean initialized = false;
120
121     /* (non-Javadoc)
122      * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
123      */

124     public void recycle() {
125         if (this.manager != null) {
126             this.manager.release(this.profileStore);
127             this.manager.release( (Component)this.authenticationManager);
128             this.manager.release( (Component)this.mediaManager);
129             this.manager.release( (Component)this.sessionManager);
130             this.manager.release( (Component)this.contextManager);
131             this.manager.release( (Component)this.transactionManager);
132             this.profileStore = null;
133             this.authenticationManager = null;
134             this.mediaManager = null;
135             this.transactionManager = null;
136             this.sessionManager = null;
137             this.contextManager = null;
138         }
139         this.initialized = false;
140     }
141
142     /**
143      * Get the current authentication state
144      */

145     protected RequestState getRequestState() {
146         AuthenticationManager authManager = null;
147         try {
148             authManager = (AuthenticationManager)this.manager.lookup(AuthenticationManager.ROLE);
149             return authManager.getState();
150         } catch (ComponentException ce) {
151             // ignore this here
152
return null;
153         } finally {
154             this.manager.release( (Component)authManager );
155         }
156     }
157
158     /* (non-Javadoc)
159      * @see org.apache.avalon.framework.component.Composable#compose(org.apache.avalon.framework.component.ComponentManager)
160      */

161     public void compose(ComponentManager manager)
162     throws ComponentException {
163         this.manager = manager;
164         this.resolver = (SourceResolver)manager.lookup(SourceResolver.ROLE);
165         this.xpathProcessor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE);
166     }
167
168     /* (non-Javadoc)
169      * @see org.apache.avalon.framework.component.Recomposable#recompose(org.apache.avalon.framework.component.ComponentManager)
170      */

171     public void recompose(ComponentManager manager) throws ComponentException {
172         this.manager = manager;
173     }
174
175     /* (non-Javadoc)
176      * @see org.apache.avalon.framework.activity.Disposable#dispose()
177      */

178     public void dispose() {
179         if ( this.manager != null ) {
180             this.manager.release( (Component)this.xpathProcessor );
181             this.xpathProcessor = null;
182             this.manager.release( this.resolver );
183             this.resolver = null;
184         }
185     }
186
187     /* (non-Javadoc)
188      * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
189      */

190     public void contextualize(Context context) throws ContextException {
191         this.componentContext = context;
192     }
193
194     /**
195      * Get the profile store
196      */

197     protected Store getProfileStore()
198     throws ProcessingException {
199         if (this.profileStore == null) {
200             try {
201                 this.profileStore = (Store)this.manager.lookup(Store.ROLE);
202             } catch (ComponentException ce) {
203                 throw new ProcessingException("Error during lookup of store component.", ce);
204             }
205         }
206         return this.profileStore;
207     }
208
209     /**
210      * Get the authentication manager
211      */

212     protected AuthenticationManager getAuthenticationManager()
213     throws ProcessingException {
214         if (this.authenticationManager == null) {
215             try {
216                 this.authenticationManager = (AuthenticationManager)this.manager.lookup(AuthenticationManager.ROLE);
217             } catch (ComponentException ce) {
218                 throw new ProcessingException("Error during lookup of AuthenticationManager.", ce);
219             }
220         }
221         return this.authenticationManager;
222     }
223
224     /**
225      * Get the media manager
226      */

227     protected MediaManager getMediaManager()
228     throws ProcessingException {
229         if (this.mediaManager == null) {
230             try {
231                 this.mediaManager = (MediaManager)this.manager.lookup(MediaManager.ROLE);
232             } catch (ComponentException ce) {
233                 throw new ProcessingException("Error during lookup of MediaManager.", ce);
234             }
235         }
236         return this.mediaManager;
237     }
238
239     /**
240      * Setup this component
241      */

242     protected void setup()
243     throws ProcessingException {
244         if ( !this.initialized ) {
245
246             final Request request = ContextHelper.getRequest(this.componentContext);
247
248             if ( request.getAttribute(PortalManager.ROLE) == null ) {
249
250                 request.setAttribute(PortalManager.ROLE, Boolean.TRUE);
251
252                 // Get and ignore the configuration
253
this.getConfiguration();
254
255                 try {
256                     this.changeProfile();
257                 } catch (SAXException JavaDoc se) {
258                     throw new ProcessingException(se);
259                 } catch (IOException JavaDoc ioe) {
260                     throw new ProcessingException(ioe);
261                 }
262             }
263
264             this.initialized = true;
265         }
266     }
267
268     /* (non-Javadoc)
269      * @see org.apache.cocoon.webapps.portal.components.PortalManager#configurationTest()
270      */

271     public void configurationTest()
272     throws ProcessingException, IOException JavaDoc, SAXException JavaDoc {
273         // no sync required
274
if (this.getLogger().isDebugEnabled()) {
275             this.getLogger().debug("BEGIN configurationTest");
276         }
277
278         this.setup();
279
280         // Ignore result
281
this.getConfiguration();
282
283         if (this.getLogger().isDebugEnabled()) {
284             this.getLogger().debug("END configurationTest");
285         }
286     }
287
288     /* (non-Javadoc)
289      * @see org.apache.cocoon.webapps.portal.components.PortalManager#getContext(boolean)
290      */

291     public SessionContext getContext(boolean create)
292     throws ProcessingException, IOException JavaDoc, SAXException JavaDoc {
293         // synchronized
294
if (this.getLogger().isDebugEnabled()) {
295             this.getLogger().debug("BEGIN getContext create="+create);
296         }
297         this.setup();
298         SessionContext context = null;
299
300         final Session session = this.getSessionManager().getSession(false);
301         if (session != null) {
302             synchronized(session) {
303                 String JavaDoc appName = this.getRequestState().getApplicationName();
304                 String JavaDoc attrName = PortalConstants.PRIVATE_SESSION_CONTEXT_NAME;
305                 if (appName != null) {
306                     attrName = attrName + ':' + appName;
307                 }
308                 context = this.getContextManager().getContext(attrName);
309                 if (context == null && create) {
310
311                     // create new context
312

313                     context = this.getAuthenticationManager().createApplicationContext(attrName, null, null);
314
315                 }
316             } // end synchronized
317
}
318
319         if (this.getLogger().isDebugEnabled()) {
320             this.getLogger().debug("END getContext context="+context);
321         }
322         return context;
323     }
324
325     /* (non-Javadoc)
326      * @see org.apache.cocoon.webapps.portal.components.PortalManager#streamConfiguration(org.apache.cocoon.xml.XMLConsumer, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
327      */

328     public void streamConfiguration(XMLConsumer consumer,
329                                     String JavaDoc requestURI,
330                                     String JavaDoc profileID,
331                                     String JavaDoc media,
332                                     String JavaDoc contextID)
333     throws IOException JavaDoc, SAXException JavaDoc, ProcessingException {
334         // synchronized not req.
335
this.setup();
336         Response response = ContextHelper.getResponse(this.componentContext);
337
338         XMLUtils.startElement(consumer, PortalConstants.ELEMENT_CONFIGURATION);
339
340         // set the portal-page uri:
341
StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(requestURI);
342         buffer.append((requestURI.indexOf('?') == -1 ? '?' : '&'))
343             .append(PortalManagerImpl.REQ_PARAMETER_PROFILE)
344             .append('=')
345             .append(profileID);
346         String JavaDoc uri = response.encodeURL(buffer.toString());
347         XMLUtils.startElement(consumer, "uri");
348         XMLUtils.data(consumer, uri);
349         XMLUtils.endElement(consumer, "uri");
350
351         Map JavaDoc config = this.getConfiguration();
352         String JavaDoc portalURI = response.encodeURL((String JavaDoc)config.get(PortalConstants.CONF_PORTAL_URI));
353
354         XMLUtils.startElement(consumer, "portal");
355         XMLUtils.data(consumer, portalURI);
356         XMLUtils.endElement(consumer, "portal");
357
358         XMLUtils.startElement(consumer, PortalConstants.ELEMENT_PROFILE);
359         XMLUtils.data(consumer, profileID);
360         XMLUtils.endElement(consumer, PortalConstants.ELEMENT_PROFILE);
361
362         if (media != null) {
363             XMLUtils.startElement(consumer, "media");
364             XMLUtils.data(consumer, media);
365             XMLUtils.endElement(consumer, "media");
366         }
367
368         if (contextID != null) {
369             XMLUtils.startElement(consumer, "context");
370             XMLUtils.data(consumer, contextID);
371             XMLUtils.endElement(consumer, "context");
372         }
373
374         XMLUtils.endElement(consumer, PortalConstants.ELEMENT_CONFIGURATION);
375     }
376
377     /* (non-Javadoc)
378      * @see org.apache.cocoon.webapps.portal.components.PortalManager#showAdminConf(org.apache.cocoon.xml.XMLConsumer)
379      */

380     public void showAdminConf(XMLConsumer consumer)
381     throws SAXException JavaDoc, ProcessingException, IOException JavaDoc {
382         // synchronized
383
if (this.getLogger().isDebugEnabled()) {
384             this.getLogger().debug("BEGIN showAdminConf consumer=" + consumer);
385         }
386         this.setup();
387         Request request = ContextHelper.getRequest(this.componentContext);
388         try {
389             String JavaDoc profileID = "global";
390             String JavaDoc copletID = request.getParameter(PortalManagerImpl.REQ_PARAMETER_COPLET);
391
392             SessionContext context = this.getContext(true);
393
394             Map JavaDoc configuration = this.getConfiguration();
395
396             DocumentFragment JavaDoc copletsFragment = (DocumentFragment JavaDoc)context.getAttribute(ATTRIBUTE_ADMIN_COPLETS);
397             String JavaDoc command = request.getParameter(PortalManagerImpl.REQ_PARAMETER_ADMIN_COPLETS);
398             if (command != null && copletsFragment != null) {
399                 try {
400                     this.getTransactionManager().startWritingTransaction(context);
401                     // save : save coplets base
402
// new : new coplet
403
// delete : use id to delete coplet
404
// change : change the coplet
405
// cache : cleans the cache
406
if (command.equals("delete") && copletID != null) {
407                         Node JavaDoc coplet = DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets/coplet[@id='"+copletID+"']", this.xpathProcessor);
408                         if (coplet != null) {
409                             coplet.getParentNode().removeChild(coplet);
410                         }
411                     } else if (command.equals("change") && copletID != null) {
412                         Node JavaDoc coplet = DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets/coplet[@id='"+copletID+"']", this.xpathProcessor);
413                         if (coplet != null) {
414                             // now get the information
415
String JavaDoc value;
416
417                             value = request.getParameter("portaladmin_title");
418                             if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "title", this.xpathProcessor), value);
419
420                             value = request.getParameter("portaladmin_mand");
421                             if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "configuration/mandatory", this.xpathProcessor), value);
422
423                             value = request.getParameter("portaladmin_sizable");
424                             if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "configuration/sizable", this.xpathProcessor), value);
425
426                             value = request.getParameter("portaladmin_active");
427                             if (value != null) DOMUtil.setValueOfNode(DOMUtil.getSingleNode(coplet, "configuration/active", this.xpathProcessor), value);
428
429                             value = request.getParameter("portaladmin_handsize");
430                             if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesSizable", this.xpathProcessor), value);
431
432                             value = request.getParameter("portaladmin_handpar");
433                             if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesParameters", this.xpathProcessor), value);
434
435                             value = request.getParameter("portaladmin_timeout");
436                             if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/timeout", this.xpathProcessor), value);
437
438                             value = request.getParameter("portaladmin_customizable");
439                             if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/customizable", this.xpathProcessor), value);
440
441                             value = request.getParameter("portaladmin_persistent");
442                             if (value != null) DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/persistent", this.xpathProcessor), value);
443
444                             String JavaDoc resource = request.getParameter("portaladmin_resource");
445                             if (resource != null) {
446                                 Element JavaDoc resourceNode = (Element JavaDoc)DOMUtil.getSingleNode(coplet, "resource", this.xpathProcessor);
447                                 resourceNode.getParentNode().removeChild(resourceNode);
448                                 resourceNode = coplet.getOwnerDocument().createElementNS(null, "resource");
449                                 resourceNode.setAttributeNS(null, "uri", resource);
450                                 coplet.appendChild(resourceNode);
451                             }
452                             resource = request.getParameter("portaladmin_cust");
453                             boolean isCustom = DOMUtil.getValueAsBooleanOf(coplet, "configuration/customizable", false, this.xpathProcessor);
454                             if (resource != null && isCustom ) {
455                                 Element JavaDoc resourceNode = (Element JavaDoc)DOMUtil.getSingleNode(coplet, "customization", this.xpathProcessor);
456                                 if (resourceNode != null) resourceNode.getParentNode().removeChild(resourceNode);
457                                 resourceNode = coplet.getOwnerDocument().createElementNS(null, "customization");
458                                 resourceNode.setAttributeNS(null, "uri", resource);
459                                 coplet.appendChild(resourceNode);
460                             }
461                             if (!isCustom) {
462                                 Element JavaDoc resourceNode = (Element JavaDoc)DOMUtil.getSingleNode(coplet, "customization", this.xpathProcessor);
463                                 if (resourceNode != null) resourceNode.getParentNode().removeChild(resourceNode);
464                             }
465
466                             // transformations
467
value = request.getParameter("portaladmin_newxsl");
468                             if (value != null) {
469                                 Element JavaDoc tNode = (Element JavaDoc)DOMUtil.selectSingleNode(coplet, "transformation", this.xpathProcessor);
470                                 Element JavaDoc sNode = tNode.getOwnerDocument().createElementNS(null, "stylesheet");
471                                 tNode.appendChild(sNode);
472                                 sNode.appendChild(sNode.getOwnerDocument().createTextNode(value));
473                             }
474
475                             // now get all transformation stylesheets, mark
476
// all stylesheets which should be deleted with
477
// an attribute delete
478
Enumeration JavaDoc keys = request.getParameterNames();
479                             Element JavaDoc sNode;
480                             String JavaDoc key;
481                             while (keys.hasMoreElements() ) {
482                                 key = (String JavaDoc)keys.nextElement();
483                                 if (key.startsWith("portaladmin_xsl_") ) {
484                                     value = key.substring(key.lastIndexOf('_')+ 1);
485                                     sNode = (Element JavaDoc)DOMUtil.getSingleNode(coplet, "transformation/stylesheet[position()="+value+"]", this.xpathProcessor);
486                                     if (sNode != null) {
487                                         String JavaDoc xslName = request.getParameter(key);
488                                         if (xslName.equals("true") ) xslName = "**STYLESHEET**";
489                                         DOMUtil.setValueOfNode(sNode, xslName);
490                                     }
491                                 } else if (key.startsWith("portaladmin_delxsl_") ) {
492                                     value = key.substring(key.lastIndexOf('_')+ 1);
493                                     sNode = (Element JavaDoc)DOMUtil.getSingleNode(coplet, "transformation/stylesheet[position()="+value+"]", this.xpathProcessor);
494                                     if (sNode != null) {
495                                         sNode.setAttributeNS(null, "delete", "true");
496                                     }
497                                 }
498                             }
499                             NodeList JavaDoc delete = DOMUtil.selectNodeList(coplet, "transformation/stylesheet[@delete]", this.xpathProcessor);
500                             if (delete != null) {
501                                 for(int i=0; i < delete.getLength(); i++) {
502                                     delete.item(i).getParentNode().removeChild(delete.item(i));
503                                 }
504                             }
505                         }
506                     } else if (command.equals("new") ) {
507                         // first we have to invent a new coplet id!
508
int index = 0;
509                         boolean found = false;
510                         Element JavaDoc coplet;
511                         Element JavaDoc subNode;
512
513                         while (!found) {
514                             copletID = "S"+index;
515                             coplet = (Element JavaDoc)DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets/coplet[@id='"+copletID+"']", this.xpathProcessor);
516                             if (coplet == null) {
517                                 found = true;
518                             } else {
519                                 index++;
520                             }
521                         }
522                         coplet = copletsFragment.getOwnerDocument().createElementNS(null, "coplet");
523                         coplet.setAttributeNS(null, "id", copletID);
524                         subNode = coplet.getOwnerDocument().createElementNS(null, "resource");
525                         coplet.appendChild(subNode);
526                         subNode.setAttributeNS(null, "uri", "uri_in_sitemap");
527
528                         String JavaDoc title = request.getParameter("portaladmin_title");
529                         if (title == null || title.trim().length() == 0) title = "**NEW COPLET**";
530                         DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/mandatory", this.xpathProcessor), "false");
531                         DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/sizable", this.xpathProcessor), "true");
532                         DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/active", this.xpathProcessor), "false");
533                         DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesParameters", this.xpathProcessor), "true");
534                         DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "configuration/handlesSizable", this.xpathProcessor), "false");
535                         DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "title", this.xpathProcessor), title);
536                         DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "status/visible", this.xpathProcessor), "true");
537                         DOMUtil.setValueOfNode(DOMUtil.selectSingleNode(coplet, "status/size", this.xpathProcessor), "max");
538                         DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets", this.xpathProcessor).appendChild(coplet);
539                     } else if (command.equals("save") ) {
540
541                         SourceParameters pars = new SourceParameters();
542                         pars.setSingleParameterValue("profile", "coplet-base");
543                         RequestState state = this.getRequestState();
544                         pars.setSingleParameterValue("application", state.getApplicationName());
545                         pars.setSingleParameterValue("handler", state.getHandlerName());
546
547                         String JavaDoc saveResource = (String JavaDoc)configuration.get(PortalConstants.CONF_COPLETBASE_SAVE_RESOURCE);
548
549                         if (saveResource == null) {
550                             throw new ProcessingException("portal: No save resource defined for type coplet-base.");
551                         } else {
552
553                             SourceUtil.writeDOM(saveResource,
554                                                 null,
555                                                 pars,
556                                                 copletsFragment,
557                                                 this.resolver,
558                                                 "xml");
559
560                             // now the hardest part, clean up the whole cache
561
this.cleanUpCache(null, null, configuration);
562                         }
563                     }
564                 } finally {
565                     this.getTransactionManager().stopWritingTransaction(context);
566                 }
567             }
568
569             // general commands
570
if (command != null && command.equals("cleancache") ) {
571                 this.cleanUpCache(null, null, configuration);
572             }
573
574             String JavaDoc state = request.getParameter(PortalManagerImpl.REQ_PARAMETER_STATE);
575             if (state == null) {
576                 state = (String JavaDoc)context.getAttribute(ATTRIBUTE_ADMIN_STATE, PortalConstants.STATE_MAIN);
577             }
578
579             // now start producing xml:
580
consumer.startElement("", PortalConstants.ELEMENT_ADMINCONF, PortalConstants.ELEMENT_ADMINCONF, XMLUtils.EMPTY_ATTRIBUTES);
581
582             context.setAttribute(ATTRIBUTE_ADMIN_STATE, state);
583             consumer.startElement("", PortalConstants.ELEMENT_STATE, PortalConstants.ELEMENT_STATE, XMLUtils.EMPTY_ATTRIBUTES);
584             consumer.characters(state.toCharArray(), 0, state.length());
585             consumer.endElement("", PortalConstants.ELEMENT_STATE, PortalConstants.ELEMENT_STATE);
586
587             if (state.equals(PortalConstants.STATE_MAIN) ) {
588
589                 Document JavaDoc rolesDF = this.getRoles();
590                 Node JavaDoc roles = null;
591                 if (rolesDF != null) roles = DOMUtil.getSingleNode(rolesDF, "roles", this.xpathProcessor);
592                 IncludeXMLConsumer.includeNode(roles, consumer, consumer);
593             }
594
595             if (state.equals(PortalConstants.STATE_MAIN_ROLE) ) {
596
597                 Document JavaDoc rolesDF = this.getRoles();
598                 Node JavaDoc roles = null;
599                 if (rolesDF != null) roles = DOMUtil.getSingleNode(rolesDF, "roles", this.xpathProcessor);
600                 IncludeXMLConsumer.includeNode(roles, consumer, consumer);
601
602                 String JavaDoc role = request.getParameter(PortalManagerImpl.REQ_PARAMETER_ROLE);
603                 if (role == null) {
604                     role = (String JavaDoc)context.getAttribute(ATTRIBUTE_ADMIN_ROLE);
605                 }
606                 context.setAttribute(ATTRIBUTE_ADMIN_ROLE, role);
607                 if (role != null) {
608                     XMLUtils.startElement(consumer, "roleusers");
609                     XMLUtils.startElement(consumer, "name");
610                     XMLUtils.data(consumer, role);
611                     XMLUtils.endElement(consumer, "name");
612                     Document JavaDoc userDF = this.getUsers(role, null);
613                     Node JavaDoc users = null;
614                     if (userDF != null) users = DOMUtil.getSingleNode(userDF, "users", this.xpathProcessor);
615                     IncludeXMLConsumer.includeNode(users, consumer, consumer);
616                     XMLUtils.endElement(consumer, "roleusers");
617                 }
618             }
619
620             if (state.equals(PortalConstants.STATE_GLOBAL)) {
621                 profileID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL, null, null, true);
622                 Map JavaDoc profile = this.retrieveProfile(profileID);
623                 if (profile == null) {
624                     this.createProfile(context, PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL, null, null, true);
625                     profile = this.retrieveProfile(profileID);
626                 }
627                 this.showPortal(consumer, true, context, profile, profileID);
628             }
629
630             if (state.equals(PortalConstants.STATE_ROLE) ) {
631                 String JavaDoc role = request.getParameter(PortalManagerImpl.REQ_PARAMETER_ROLE);
632                 if (role == null) {
633                     role = (String JavaDoc)context.getAttribute(ATTRIBUTE_ADMIN_ROLE);
634                 }
635                 context.setAttribute(ATTRIBUTE_ADMIN_ROLE, role);
636                 if (role != null) {
637                     consumer.startElement("", PortalConstants.ELEMENT_ROLE, PortalConstants.ELEMENT_ROLE, XMLUtils.EMPTY_ATTRIBUTES);
638                     consumer.characters(role.toCharArray(), 0, role.length());
639                     consumer.endElement("", PortalConstants.ELEMENT_ROLE, PortalConstants.ELEMENT_ROLE);
640                     profileID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_ROLE, role, null, true);
641                     Map JavaDoc profile = this.retrieveProfile(profileID);
642                     if (profile == null) {
643                         this.createProfile(context, PortalManagerImpl.BUILDTYPE_VALUE_ROLE, role, null, true);
644                         profile = this.retrieveProfile(profileID);
645                     }
646                     this.showPortal(consumer, true, context, profile, profileID);
647                 }
648             }
649             if (state.equals(PortalConstants.STATE_USER) ) {
650                 String JavaDoc role = request.getParameter(PortalManagerImpl.REQ_PARAMETER_ROLE);
651                 String JavaDoc id = request.getParameter(PortalManagerImpl.REQ_PARAMETER_ID);
652                 if (role == null) {
653                     role = (String JavaDoc)context.getAttribute(ATTRIBUTE_ADMIN_ROLE);
654                 }
655                 if (id == null) {
656                     id = (String JavaDoc)context.getAttribute(ATTRIBUTE_ADMIN_ID);
657                 }
658                 context.setAttribute(ATTRIBUTE_ADMIN_ID, id);
659                 context.setAttribute(ATTRIBUTE_ADMIN_ROLE, role);
660                 if (role != null && id != null) {
661                     consumer.startElement("", PortalConstants.ELEMENT_ROLE, PortalConstants.ELEMENT_ROLE, XMLUtils.EMPTY_ATTRIBUTES);
662                     consumer.characters(role.toCharArray(), 0, role.length());
663                     consumer.endElement("", PortalConstants.ELEMENT_ROLE, PortalConstants.ELEMENT_ROLE);
664                     consumer.startElement("", PortalConstants.ELEMENT_ID, PortalConstants.ELEMENT_ID, XMLUtils.EMPTY_ATTRIBUTES);
665                     consumer.characters(id.toCharArray(), 0, id.length());
666                     consumer.endElement("", PortalConstants.ELEMENT_ID, PortalConstants.ELEMENT_ID);
667
668                     profileID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_ID, role, id, true);
669                     Map JavaDoc profile = this.retrieveProfile(profileID);
670                     if (profile == null) {
671                         this.createProfile(context, PortalManagerImpl.BUILDTYPE_VALUE_ID, role, id, true);
672                         profile = this.retrieveProfile(profileID);
673                     }
674                     this.showPortal(consumer, true, context, profile, profileID);
675                 }
676             }
677             // one coplet
678
if (state.equals(PortalConstants.STATE_COPLET) ) {
679                 if (copletsFragment != null && copletID != null) {
680                     Node JavaDoc coplet = DOMUtil.getSingleNode(copletsFragment, "coplets-profile/coplets/coplet[@id='"+copletID+"']", this.xpathProcessor);
681                     if (coplet != null) {
682                         IncludeXMLConsumer.includeNode(coplet, consumer, consumer);
683                     }
684                 } else {
685                     state = PortalConstants.STATE_COPLETS;
686                 }
687             }
688             if (state.equals(PortalConstants.STATE_COPLETS) ) {
689                 consumer.startElement("", PortalConstants.ELEMENT_COPLETS, PortalConstants.ELEMENT_COPLETS, XMLUtils.EMPTY_ATTRIBUTES);
690
691                 // load the base coplets profile
692
if (copletsFragment == null) {
693                     SourceParameters pars = new SourceParameters();
694                     RequestState reqstate = this.getRequestState();
695                     pars.setSingleParameterValue("application", reqstate.getApplicationName());
696                     String JavaDoc res = (String JavaDoc)configuration.get(PortalConstants.CONF_COPLETBASE_RESOURCE);
697                     if (res == null) {
698                         throw new ProcessingException("No configuration for portal-coplet base profile found.");
699                     }
700                     copletsFragment = SourceUtil.readDOM(res,
701                                                          null,
702                                                          pars,
703                                                          this.resolver);
704                     context.setAttribute(ATTRIBUTE_ADMIN_COPLETS, copletsFragment);
705                 }
706                 IncludeXMLConsumer.includeNode(DOMUtil.selectSingleNode(copletsFragment,
707                                    "coplets-profile", this.xpathProcessor), consumer, consumer);
708                 consumer.endElement("", PortalConstants.ELEMENT_COPLETS, PortalConstants.ELEMENT_COPLETS);
709             }
710
711             // configuration
712
this.streamConfiguration(consumer, request.getRequestURI(), profileID, null, null);
713
714             consumer.endElement("", PortalConstants.ELEMENT_ADMINCONF, PortalConstants.ELEMENT_ADMINCONF);
715         } catch (javax.xml.transform.TransformerException JavaDoc local) {
716             throw new ProcessingException("TransformerException: " + local, local);
717         }
718
719         if (this.getLogger().isDebugEnabled() ) {
720             this.getLogger().debug("END showAdminConf");
721         }
722     }
723
724     /* (non-Javadoc)
725      * @see org.apache.cocoon.webapps.portal.components.PortalManager#getStatusProfile()
726      */

727     public Element JavaDoc getStatusProfile()
728     throws SAXException JavaDoc, IOException JavaDoc, ProcessingException {
729         // synchronized
730
if (this.getLogger().isDebugEnabled() ) {
731             this.getLogger().debug("BEGIN getStatusProfile");
732         }
733         this.setup();
734         SessionContext context = this.getContext(true);
735         String JavaDoc profileID = null;
736         Map JavaDoc storedProfile = null;
737         Element JavaDoc statusProfile = null;
738
739         if (context.getAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ROLE) != null) {
740             profileID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_ID,
741                   (String JavaDoc)context.getAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ROLE),
742                   (String JavaDoc)context.getAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ID), false);
743             storedProfile = this.retrieveProfile(profileID);
744         }
745
746         if (storedProfile != null) {
747             DocumentFragment JavaDoc profile = (DocumentFragment JavaDoc)storedProfile.get(PortalConstants.PROFILE_PROFILE);
748             try {
749                 statusProfile = (Element JavaDoc)DOMUtil.getSingleNode(profile, "profile/status-profile", this.xpathProcessor);
750             } catch (javax.xml.transform.TransformerException JavaDoc ignore) {
751             }
752         }
753
754         if (this.getLogger().isDebugEnabled() ) {
755             this.getLogger().debug("END getStatusProfile statusProfile="+(statusProfile == null ? "null" : XMLUtils.serializeNode(statusProfile, XMLUtils.createPropertiesForXML(false))));
756         }
757         return statusProfile;
758     }
759
760     /* (non-Javadoc)
761      * @see org.apache.cocoon.webapps.portal.components.PortalManager#showPortal(org.apache.cocoon.xml.XMLConsumer, boolean, boolean)
762      */

763     public void showPortal(XMLConsumer consumer,
764                            boolean configMode,
765                            boolean adminProfile)
766     throws SAXException JavaDoc, ProcessingException, IOException JavaDoc {
767         // synchronized
768
if (this.getLogger().isDebugEnabled()) {
769             this.getLogger().debug("BEGIN showPortal consumer=" + consumer+", configMode="+
770                              configMode+", adminProfile="+adminProfile);
771         }
772         this.setup();
773
774         SessionContext context = this.getContext(true);
775         String JavaDoc profileID = null;
776         Map JavaDoc storedProfile = null;
777
778         if (this.getLogger().isDebugEnabled()) {
779             this.getLogger().debug("start portal generation");
780         }
781         if (context.getAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ROLE) != null) {
782             profileID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_ID,
783                   (String JavaDoc)context.getAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ROLE),
784                   (String JavaDoc)context.getAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ID), adminProfile);
785             storedProfile = this.retrieveProfile(profileID);
786         }
787         if (storedProfile == null) {
788
789             if (this.getLogger().isDebugEnabled()) {
790                 this.getLogger().debug("start building profile");
791             }
792             this.createProfile(context, PortalManagerImpl.BUILDTYPE_VALUE_ID, null, null, adminProfile);
793             // get the profileID
794
profileID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_ID,
795                     (String JavaDoc)context.getAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ROLE),
796                     (String JavaDoc)context.getAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ID), adminProfile);
797             storedProfile = this.retrieveProfile(profileID);
798             if (storedProfile == null) {
799                 throw new ProcessingException("portal: No portal profile found.");
800             }
801             if (this.getLogger().isDebugEnabled() ) {
802                 this.getLogger().debug("end building profile");
803             }
804         }
805
806         if (this.getLogger().isDebugEnabled() ) {
807             this.getLogger().debug("start showing profile");
808         }
809         this.showPortal(consumer,
810                         configMode,
811                         context,
812                         storedProfile,
813                         profileID);
814         if (this.getLogger().isDebugEnabled() ) {
815             this.getLogger().debug("end showing profile");
816             this.getLogger().debug("end portal generation");
817         }
818         if (this.getLogger().isDebugEnabled() ) {
819             this.getLogger().debug("END showPortal");
820         }
821     }
822
823     /**
824      * Stream all layout information for the current portal
825      * to the consumer.
826      * The resulting XML:
827      * <layout>
828      * <portal>
829      * ...
830      * </portal>
831      * <coplets>
832      * ...
833      * </coplets>
834      * </layout>
835      */

836     public static void streamLayoutProfile(XMLConsumer consumer,
837                                            Map JavaDoc portalLayouts,
838                                            Map JavaDoc copletLayouts,
839                                            String JavaDoc mediaType)
840     throws SAXException JavaDoc {
841         Element JavaDoc element;
842         NodeList JavaDoc childs;
843         Attributes JavaDoc attr = new AttributesImpl JavaDoc();
844
845         consumer.startElement("", PortalConstants.ELEMENT_LAYOUT, PortalConstants.ELEMENT_LAYOUT, attr);
846
847         // first: layout of portal
848
consumer.startElement("", PortalConstants.ELEMENT_PORTAL, PortalConstants.ELEMENT_PORTAL, attr);
849
850         element = (Element JavaDoc)portalLayouts.get(mediaType);
851         childs = element.getChildNodes();
852         for(int ci = 0; ci < childs.getLength(); ci++) {
853             IncludeXMLConsumer.includeNode(childs.item(ci),
854                                       consumer,
855                                       consumer);
856         }
857         consumer.endElement("", PortalConstants.ELEMENT_PORTAL, PortalConstants.ELEMENT_PORTAL);
858
859         // second: layout of coplets
860
consumer.startElement("", PortalConstants.ELEMENT_COPLETS, PortalConstants.ELEMENT_COPLETS, attr);
861         element = (Element JavaDoc)copletLayouts.get(mediaType);
862         childs = element.getChildNodes();
863         for(int ci = 0; ci < childs.getLength(); ci++) {
864             IncludeXMLConsumer.includeNode(childs.item(ci),
865                                       consumer,
866                                       consumer);
867         }
868         consumer.endElement("", PortalConstants.ELEMENT_COPLETS, PortalConstants.ELEMENT_COPLETS);
869
870         consumer.endElement("", PortalConstants.ELEMENT_LAYOUT, PortalConstants.ELEMENT_LAYOUT);
871     }
872
873     /**
874      * Show the portal.
875      * The portal is included in the current stream.
876      */

877     private void showPortal(XMLConsumer consumer,
878                            boolean configMode,
879                            SessionContext context,
880                            Map JavaDoc storedProfile,
881                            String JavaDoc profileID)
882     throws SAXException JavaDoc, ProcessingException, IOException JavaDoc {
883         // synchronized
884
if (this.getLogger().isDebugEnabled() ) {
885             this.getLogger().debug("BEGIN showPortal consumer=" + consumer+", configMode="+configMode+", context="+context+
886                 ", profile="+storedProfile);
887         }
888         Request request = ContextHelper.getRequest(this.componentContext);
889         try {
890             this.getTransactionManager().startReadingTransaction(context);
891
892             DocumentFragment JavaDoc profile;
893             Map JavaDoc defaultCoplets;
894             Map JavaDoc mediaCoplets;
895             Map JavaDoc portalLayouts;
896             Map JavaDoc copleyLayouts;
897             Node JavaDoc[] miscNodes;
898             String JavaDoc mediaType = this.getMediaManager().getMediaType();
899
900             profile = (DocumentFragment JavaDoc)storedProfile.get(PortalConstants.PROFILE_PROFILE);
901             portalLayouts = (Map JavaDoc)storedProfile.get(PortalConstants.PROFILE_PORTAL_LAYOUTS);
902             copleyLayouts = (Map JavaDoc)storedProfile.get(PortalConstants.PROFILE_COPLET_LAYOUTS);
903             miscNodes = (Node JavaDoc[])storedProfile.get(PortalConstants.PROFILE_MISC_POINTER);
904             defaultCoplets = (Map JavaDoc)storedProfile.get(PortalConstants.PROFILE_DEFAULT_COPLETS);
905             mediaCoplets = (Map JavaDoc)storedProfile.get(PortalConstants.PROFILE_MEDIA_COPLETS);
906             if (profile == null ||
907                 defaultCoplets == null ||
908                 mediaCoplets == null ||
909                 portalLayouts == null ||
910                 copleyLayouts == null ||
911                 miscNodes == null) {
912                 throw new ProcessingException("portal: No portal profile found.");
913             }
914
915             // get the configuration
916
Map JavaDoc config = this.getConfiguration();
917             if (config == null) {
918                 throw new ProcessingException("No configuration for portal found.");
919             }
920             boolean processCopletsParallel = false;
921             long defaultCopletTimeout = 600000;
922
923             Boolean JavaDoc boolValue = (Boolean JavaDoc)config.get(PortalConstants.CONF_PARALLEL_COPLETS);
924             if (boolValue != null) processCopletsParallel = boolValue.booleanValue();
925             Long JavaDoc longValue = (Long JavaDoc)config.get(PortalConstants.CONF_COPLET_TIMEOUT);
926             if (longValue != null) defaultCopletTimeout = longValue.longValue();
927
928             Element JavaDoc element;
929
930             // now start producing xml:
931
AttributesImpl JavaDoc attr = new AttributesImpl JavaDoc();
932             if (configMode) {
933                 XMLUtils.startElement(consumer, PortalConstants.ELEMENT_PORTALCONF);
934             } else {
935                 XMLUtils.startElement(consumer, PortalConstants.ELEMENT_PORTAL);
936             }
937
938             // configuration
939
this.streamConfiguration(consumer, request.getRequestURI(), profileID, mediaType, null);
940
941             // LAYOUT:
942
if (configMode) {
943                 IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String JavaDoc[] {"profile","layout-profile"}, false),
944                      consumer, consumer);
945                 // copletsConfiguration (only for configMode)
946
IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String JavaDoc[] {"profile","coplets-profile"}, false),
947                      consumer, consumer);
948                 IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String JavaDoc[] {"profile","type-profile","typedefs"}, false),
949                      consumer, consumer);
950                 IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String JavaDoc[] {"profile","portal-profile"}, false),
951                      consumer, consumer);
952                 IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String JavaDoc[] {"profile","personal-profile"}, false),
953                      consumer, consumer);
954                 IncludeXMLConsumer.includeNode(DOMUtil.getFirstNodeFromPath(profile, new String JavaDoc[] {"profile","status-profile"}, false),
955                      consumer, consumer);
956             } else {
957                 PortalManagerImpl.streamLayoutProfile(consumer, portalLayouts, copleyLayouts, mediaType);
958             }
959             // END LAYOUT
960

961             if (!configMode) {
962                 Element JavaDoc statusProfile = (Element JavaDoc)DOMUtil.getFirstNodeFromPath(profile, new String JavaDoc[] {"profile","status-profile"}, false);
963
964                 String JavaDoc copletNotAvailableMessage = "The coplet is currently not available.";
965                 Node JavaDoc messages = miscNodes[PortalConstants.PROFILE_MISC_MESSAGES_NODE];
966                 if (messages != null) {
967                     messages = DOMUtil.getFirstNodeFromPath(messages, new String JavaDoc[] {"coplet_not_available"}, false);
968                     if (messages != null) copletNotAvailableMessage = DOMUtil.getValueOfNode(messages,
969                          copletNotAvailableMessage);
970                 }
971
972                 // LOAD COPLETS
973
List JavaDoc[] copletContents;
974
975                 List JavaDoc[] temp = (List JavaDoc[])context.getAttribute(PortalConstants.ATTRIBUTE_COPLET_REPOSITORY);
976                 if (temp != null) {
977                     copletContents = new List JavaDoc[temp.length];
978                     for (int i = 0; i < temp.length; i++) {
979                         if (temp[i] == null) {
980                             copletContents[i] = null;
981                         } else {
982                             copletContents[i] = new ArrayList JavaDoc(temp[i]);
983                         }
984                     }
985                 } else {
986                     copletContents = new List JavaDoc[PortalConstants.MAX_COLUMNS+2];
987                     context.setAttribute(PortalConstants.ATTRIBUTE_COPLET_REPOSITORY, copletContents);
988                 }
989
990                 if (copletContents[0] == null) {
991                     copletContents[0] = new ArrayList JavaDoc(1);
992                 } else {
993                     copletContents[0].clear();
994                 }
995                 if (copletContents[1] == null) {
996                     copletContents[1] = new ArrayList JavaDoc(1);
997                 } else {
998                     copletContents[1].clear();
999                 }
1000
1001                // test for header
1002
String JavaDoc value;
1003                value = DOMUtil.getValueOfNode(miscNodes[PortalConstants.PROFILE_MISC_HEADER_NODE]);
1004                if (value != null && new Boolean JavaDoc(value).booleanValue()) {
1005                    element = (Element JavaDoc)miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE];
1006                    if (element != null) {
1007                        this.loadCoplets(element,
1008                                         defaultCoplets,
1009                                         mediaCoplets,
1010                                         copletContents[0],
1011                                         processCopletsParallel,
1012                                         defaultCopletTimeout,
1013                                         statusProfile);
1014                    }
1015                }
1016
1017                // content
1018
value = DOMUtil.getValueOfNode(miscNodes[PortalConstants.PROFILE_MISC_COLUMNS_NODE]);
1019
1020                // for a simpler XSL-Stylesheet: The columns must be inserted in the
1021
// correct order!!!
1022
if (value != null && new Integer JavaDoc(value).intValue() > 0) {
1023
1024                    Element JavaDoc columnElement;
1025                    int columns = new Integer JavaDoc(value).intValue();
1026                    if (columns > PortalConstants.MAX_COLUMNS) {
1027                        throw new ProcessingException("portal: Maximum number of columns supported is: "+PortalConstants.MAX_COLUMNS);
1028                    }
1029
1030                    for(int colindex = 1; colindex <= columns; colindex++) {
1031                        if (copletContents[colindex+1] == null) {
1032                            copletContents[colindex+1] = new ArrayList JavaDoc(10);
1033                        } else {
1034                            copletContents[colindex+1].clear();
1035                        }
1036                        columnElement = (Element JavaDoc)miscNodes[7 + colindex];
1037                        element = (Element JavaDoc)DOMUtil.getFirstNodeFromPath(columnElement, new String JavaDoc[] {"coplets"}, false);
1038                        if (element != null) {
1039                            this.loadCoplets(element,
1040                                             defaultCoplets,
1041                                             mediaCoplets,
1042                                             copletContents[colindex+1],
1043                                             processCopletsParallel,
1044                                             defaultCopletTimeout,
1045                                             statusProfile);
1046                        }
1047
1048                    }
1049                    for(int colindex = columns+2; colindex <= PortalConstants.MAX_COLUMNS+1; colindex++) {
1050                        if (copletContents[colindex] != null) {
1051                            copletContents[colindex] = null;
1052                        }
1053                    }
1054
1055                } else {
1056                    for(int colindex = 1; colindex <= PortalConstants.MAX_COLUMNS; colindex++) {
1057                        if (copletContents[colindex+1] != null) {
1058                            copletContents[colindex+1] = null;
1059                        }
1060                    }
1061                }
1062
1063                // test for footer
1064
value = DOMUtil.getValueOfNode(miscNodes[PortalConstants.PROFILE_MISC_FOOTER_NODE]);
1065                if (value != null && new Boolean JavaDoc(value).booleanValue()) {
1066                    element = (Element JavaDoc)miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE];
1067                    if (element != null) {
1068                        this.loadCoplets(element,
1069                                         defaultCoplets,
1070                                         mediaCoplets,
1071                                         copletContents[1],
1072                                         processCopletsParallel,
1073                                         defaultCopletTimeout,
1074                                         statusProfile);
1075                    }
1076                }
1077                // END LOAD COPLETS
1078

1079                // DESIGN
1080
// test for header
1081
if (copletContents[0].size() > 0) {
1082                    consumer.startElement("", "header", "header", attr);
1083                    this.processCopletList(copletContents[0], consumer, copletNotAvailableMessage, defaultCopletTimeout);
1084                    consumer.endElement("", "header", "header");
1085                }
1086
1087                // content
1088
value = DOMUtil.getValueOfNode(miscNodes[PortalConstants.PROFILE_MISC_COLUMNS_NODE]);
1089
1090                // for a simpler XSL-Stylesheet: The columns must be inserted in the
1091
// correct order!!!
1092
if (value != null && new Integer JavaDoc(value).intValue() > 0) {
1093                    attr.addAttribute("", "number", "number", "CDATA", value);
1094                    XMLUtils.startElement(consumer, "columns", attr);
1095                    attr.clear();
1096
1097                    int columns = new Integer JavaDoc(value).intValue();
1098                    if (columns > PortalConstants.MAX_COLUMNS) {
1099                        throw new ProcessingException("portal: Maximum number of columns supported is: "+PortalConstants.MAX_COLUMNS);
1100                    }
1101
1102                    // determine the width of the columns
1103
String JavaDoc[] width = new String JavaDoc[columns];
1104                    int normalWidth = 100 / columns;
1105                    Element JavaDoc columnElement;
1106
1107                    for(int colindex = 1; colindex <= columns; colindex++) {
1108                        columnElement = (Element JavaDoc)miscNodes[7 + colindex];
1109                        value = DOMUtil.getValueOf(columnElement, "width", this.xpathProcessor);
1110                        if (value == null) {
1111                            width[colindex-1] = "" + normalWidth + "%";
1112                        } else {
1113                            width[colindex-1] = value;
1114                        }
1115                    }
1116
1117                    for(int colindex = 1; colindex <= columns; colindex++) {
1118                        attr.addAttribute("", "position", "position", "CDATA", "" + colindex);
1119                        attr.addAttribute("", "width", "width", "CDATA", width[colindex-1]);
1120                        XMLUtils.startElement(consumer, "column", attr);
1121                        attr.clear();
1122
1123                        this.processCopletList(copletContents[colindex+1], consumer, copletNotAvailableMessage, defaultCopletTimeout);
1124
1125                        XMLUtils.endElement(consumer, "column");
1126                    }
1127                    XMLUtils.endElement(consumer, "columns");
1128                } else {
1129                    attr.addAttribute("", "number", "number", "CDATA", "0");
1130                    XMLUtils.startElement(consumer, "columns", attr);
1131                    XMLUtils.endElement(consumer, "columns");
1132                    attr.clear();
1133                }
1134
1135                // test for footer
1136
if (copletContents[1].size() > 0) {
1137                    XMLUtils.startElement(consumer, "footer");
1138                    this.processCopletList(copletContents[1], consumer, copletNotAvailableMessage, defaultCopletTimeout);
1139                    XMLUtils.endElement(consumer, "footer");
1140                }
1141                // END DESIGN
1142

1143                for(int i=0; i<copletContents.length;i++) {
1144                    if (copletContents[i]!=null) copletContents[i].clear();
1145                }
1146
1147                // Personal information and status information
1148
this.sendEvents(consumer, DOMUtil.getFirstNodeFromPath(profile, new String JavaDoc[] {"profile","personal-profile"}, false));
1149                this.sendEvents(consumer, statusProfile);
1150            }
1151
1152            if (configMode) {
1153                XMLUtils.endElement(consumer, PortalConstants.ELEMENT_PORTALCONF);
1154            } else {
1155                XMLUtils.endElement(consumer, PortalConstants.ELEMENT_PORTAL);
1156            }
1157
1158        } catch (javax.xml.transform.TransformerException JavaDoc local) { // end synchronized
1159
throw new ProcessingException("TransformerException: " + local, local);
1160        } finally {
1161            this.getTransactionManager().stopReadingTransaction(context);
1162        }
1163        if (this.getLogger().isDebugEnabled()) {
1164            this.getLogger().debug("END showPortal");
1165        }
1166    }
1167
1168
1169    /**
1170     * Building the profile.
1171     * This includes several steps which are declared in detail inside this method...
1172     */

1173    protected void buildProfile(String JavaDoc type,
1174                             String JavaDoc role,
1175                             String JavaDoc id,
1176                             boolean adminProfile)
1177    throws ProcessingException, IOException JavaDoc, SAXException JavaDoc {
1178        // synchronized
1179
if (this.getLogger().isDebugEnabled()) {
1180            this.getLogger().debug("BEGIN buildProfile type=" + type + ", role=" + role + ", id=" +id+", adminProfile="+adminProfile);
1181        }
1182        try {
1183            // check parameter
1184
if (type == null) {
1185                throw new ProcessingException("buildProfile: Type is required");
1186            }
1187            if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL) ||
1188                type.equals(PortalManagerImpl.BUILDTYPE_VALUE_BASIC)) {
1189                // nothing to do here
1190
} else if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ROLE)) {
1191                if (role == null) {
1192                    throw new ProcessingException("buildProfile: Role is required");
1193                }
1194            } else if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID)) {
1195                if (role == null) {
1196                    throw new ProcessingException("buildProfile: Role is required");
1197                }
1198                if (id == null) {
1199                    throw new ProcessingException("buildProfile: ID is required");
1200                }
1201            } else {
1202                throw new ProcessingException("buildProfile: Type unknown: " + type);
1203            }
1204
1205            SessionContext context = this.getContext(true);
1206            try {
1207                this.getTransactionManager().startWritingTransaction(context);
1208
1209                String JavaDoc profileID = this.getProfileID(type, role, id, adminProfile);
1210                Map JavaDoc theProfile = null;
1211
1212                // get the configuration
1213
Map JavaDoc config = this.getConfiguration();
1214                if (config == null) {
1215                    throw new ProcessingException("No configuration for portal found.");
1216                }
1217
1218                // is the ID profile cached?
1219
if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID) ) {
1220                    theProfile = this.getCachedProfile(profileID, config);
1221                }
1222
1223                if (theProfile == null) {
1224
1225                    boolean doBase = false;
1226                    boolean doGlobal = false;
1227                    boolean doRole = false;
1228                    boolean doID = false;
1229                    String JavaDoc previousID;
1230
1231                    if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID)) {
1232                        doID = true;
1233                        previousID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_ROLE, role, null, adminProfile);
1234                        theProfile = this.getCachedProfile(previousID, config);
1235                        if (theProfile == null) {
1236                            doRole = true;
1237                            previousID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL, null, null, adminProfile);
1238                            theProfile = this.getCachedProfile(previousID, config);
1239                            if (theProfile == null) {
1240                                doGlobal = true;
1241                                previousID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_BASIC, null, null, adminProfile);
1242                                theProfile = this.getCachedProfile(previousID, config);
1243                            }
1244                        }
1245                    } else if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ROLE)) {
1246                        theProfile = this.getCachedProfile(profileID, config);
1247                        if (theProfile == null) {
1248                            doRole = true;
1249                            previousID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL, null, null, adminProfile);
1250                            theProfile = this.getCachedProfile(previousID, config);
1251                            if (theProfile == null) {
1252                                doGlobal = true;
1253                                previousID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_BASIC, null, null, adminProfile);
1254                                theProfile = this.getCachedProfile(previousID, config);
1255                            }
1256                        }
1257                    } else if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL)) {
1258                        theProfile = this.getCachedProfile(profileID, config);
1259                        if (theProfile == null) {
1260                            doGlobal = true;
1261                            previousID = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_BASIC, null, null, adminProfile);
1262                            theProfile = this.getCachedProfile(previousID, config);
1263                        }
1264                    } else { // basic profile
1265
theProfile = this.getCachedProfile(profileID, config);
1266                    }
1267
1268                    // build the profile
1269
if (theProfile == null) {
1270                        theProfile = new HashMap JavaDoc(8,2);
1271                        doBase = true;
1272                    }
1273
1274                    Element JavaDoc profileRoot;
1275                    DocumentFragment JavaDoc profile;
1276
1277                    if (doBase) {
1278                        // build the base level
1279
profile = this.buildBaseProfile(config, adminProfile);
1280                        profileRoot = (Element JavaDoc)profile.getFirstChild();
1281                        theProfile.put(PortalConstants.PROFILE_PROFILE, profile);
1282                        this.cacheProfile(this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_BASIC, null, null, adminProfile), theProfile, config);
1283                    } else {
1284                        profile = (DocumentFragment JavaDoc)theProfile.get(PortalConstants.PROFILE_PROFILE);
1285                        profileRoot = (Element JavaDoc)profile.getFirstChild();
1286                    }
1287
1288                    // load the global delta if type is global, role or user (but not basic!)
1289
if (doGlobal) {
1290                        this.buildGlobalProfile(profileRoot, config, adminProfile);
1291                        this.cacheProfile(this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL, null, null, adminProfile), theProfile, config);
1292                    }
1293
1294                    // load the role delta if type is role or user
1295
if (doRole) {
1296                        this.buildRoleProfile(profileRoot, config, role, adminProfile);
1297                        this.cacheProfile(this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_ROLE, role, null, adminProfile), theProfile, config);
1298                    }
1299
1300                    // load the user delta if type is user
1301
if (doID) {
1302                        this.buildUserProfile(profileRoot, config, role, id, adminProfile);
1303                    }
1304
1305                    // load the status profile when type is user
1306
if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID)) {
1307                        this.buildUserStatusProfile(profileRoot, config, role, id);
1308                    }
1309
1310                    if (!type.equals(PortalManagerImpl.BUILDTYPE_VALUE_BASIC)) {
1311                        this.buildRunProfile(theProfile, context, profile);
1312
1313                        theProfile.put(PortalConstants.PROFILE_PORTAL_LAYOUTS,
1314                               this.buildPortalLayouts(context, profile));
1315                        theProfile.put(PortalConstants.PROFILE_COPLET_LAYOUTS,
1316                               this.buildcopleyLayouts(context, profile));
1317
1318                        this.buildTypeProfile(theProfile, context, profile);
1319                    }
1320
1321                    // cache the profile, if user
1322
if (doID) {
1323                        this.cacheProfile(profileID, theProfile, config);
1324                    }
1325                } else {
1326                    // load the status profile when type is user
1327
if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID)) {
1328                        DocumentFragment JavaDoc profile = (DocumentFragment JavaDoc)theProfile.get(PortalConstants.PROFILE_PROFILE);
1329                        Element JavaDoc profileRoot = (Element JavaDoc)profile.getFirstChild();
1330                        this.buildUserStatusProfile(profileRoot, config, role, id);
1331                    }
1332                }
1333
1334                // store the whole profile
1335
this.storeProfile(profileID, theProfile);
1336
1337                // now put role and id into the context if type is ID
1338
if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID)
1339                    && !adminProfile) {
1340                    context.setAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ROLE, role);
1341                    context.setAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ID, id);
1342                }
1343            } finally {
1344                this.getTransactionManager().stopWritingTransaction(context);
1345            }// end synchronized
1346
} catch (javax.xml.transform.TransformerException JavaDoc local) {
1347            throw new ProcessingException("TransformerException: " + local, local);
1348        }
1349
1350        if (this.getLogger().isDebugEnabled()) {
1351            this.getLogger().debug("END buildProfile");
1352        }
1353    }
1354
1355    /**
1356     * Build the profile delta
1357     */

1358    private DocumentFragment JavaDoc buildProfileDelta(String JavaDoc type,
1359                                               String JavaDoc role,
1360                                               String JavaDoc id,
1361                                               boolean adminProfile)
1362    throws SAXException JavaDoc, ProcessingException, IOException JavaDoc, javax.xml.transform.TransformerException JavaDoc {
1363        // calling method must be synchronized
1364
if (this.getLogger().isDebugEnabled()) {
1365            this.getLogger().debug("END buildProfileDeltaN type="+type+", role="+role+", id="+id);
1366        }
1367
1368        Map JavaDoc originalProfile;
1369        Map JavaDoc baseProfile;
1370        String JavaDoc baseType, baseRole, baseID, rootElementName;
1371        DocumentFragment JavaDoc originalFragment;
1372        DocumentFragment JavaDoc delta;
1373        SessionContext context = this.getContext(true);
1374
1375        originalProfile = this.retrieveProfile(this.getProfileID(type, role, id, adminProfile));
1376        if (originalProfile == null) {
1377            throw new ProcessingException("buildProfileDelta: no profile found for " +
1378                   type + " - " + role + " - " + id + ".");
1379        }
1380
1381        if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID)) {
1382            baseType = PortalManagerImpl.BUILDTYPE_VALUE_ROLE;
1383            baseRole = role;
1384            baseID = null;
1385            rootElementName = "user-delta";
1386        } else if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ROLE)) {
1387            baseType = PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL;
1388            baseRole = null;
1389            baseID = null;
1390            rootElementName = "role-delta";
1391        } else if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL)) {
1392            baseType = PortalManagerImpl.BUILDTYPE_VALUE_BASIC;
1393            baseRole = null;
1394            baseID = null;
1395            rootElementName = "global-delta";
1396        } else {
1397            throw new ProcessingException("buildProfileDelta: type '"+type+"' not allowed.");
1398        }
1399
1400        // the profile is created as we dont want to use any memory representation!
1401
this.createProfile(context, baseType, baseRole, baseID, adminProfile);
1402        baseProfile = this.retrieveProfile(this.getProfileID(baseType, baseRole, baseID, adminProfile));
1403        if (baseProfile == null) {
1404            throw new ProcessingException("buildProfileDelta: no baseProfile found.");
1405        }
1406
1407        originalFragment = (DocumentFragment JavaDoc)originalProfile.get(PortalConstants.PROFILE_PROFILE);
1408        delta = originalFragment.getOwnerDocument().createDocumentFragment();
1409        delta.appendChild(delta.getOwnerDocument().createElementNS(null, rootElementName));
1410
1411        // Copy portal content
1412
Node JavaDoc profileDelta = DOMUtil.getFirstNodeFromPath(originalFragment, new String JavaDoc[] {"profile","portal-profile"}, false).cloneNode(true);
1413        delta.getFirstChild().appendChild(profileDelta);
1414
1415        // Diff layout profile, coplet profile, personal profile but not status profile!
1416
this.diff(originalFragment,
1417                 (DocumentFragment JavaDoc)baseProfile.get(PortalConstants.PROFILE_PROFILE),
1418                  "profile/layout-profile",
1419                  (Element JavaDoc)delta.getFirstChild());
1420        this.diff(originalFragment,
1421                  (DocumentFragment JavaDoc)baseProfile.get(PortalConstants.PROFILE_PROFILE),
1422                  "profile/coplets-profile",
1423                  (Element JavaDoc)delta.getFirstChild());
1424        if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL)) {
1425            profileDelta = DOMUtil.getFirstNodeFromPath(originalFragment, new String JavaDoc[] {"profile","personal-profile"}, false).cloneNode(true);
1426            delta.getFirstChild().appendChild(profileDelta);
1427        } else {
1428            this.diff(originalFragment,
1429                  (DocumentFragment JavaDoc)baseProfile.get(PortalConstants.PROFILE_PROFILE),
1430                  "profile/personal-profile",
1431                  (Element JavaDoc)delta.getFirstChild());
1432        }
1433
1434        // check for the highes coplet number
1435
Node JavaDoc[] miscNodes = (Node JavaDoc[])originalProfile.get(PortalConstants.PROFILE_MISC_POINTER);
1436        Element JavaDoc lastCoplet = (Element JavaDoc)miscNodes[PortalConstants.PROFILE_MISC_LAST_COPLET_NODE];
1437        if (lastCoplet != null) {
1438            String JavaDoc lastNumber = lastCoplet.getAttributeNS(null, "number");
1439            if (lastNumber != null) {
1440                int value = new Integer JavaDoc(lastNumber).intValue();
1441                if (value > 1000000) {
1442                    NodeList JavaDoc coplets = DOMUtil.selectNodeList(delta, "profile/portal-profile/descendant::coplet[@id and @number]", this.xpathProcessor);
1443                    if (coplets != null) {
1444                        Element JavaDoc copletNode;
1445                        String JavaDoc oldNumber;
1446                        String JavaDoc copletId;
1447                        Element JavaDoc statusNode;
1448                        boolean copletsChanged = false;
1449                        for(int i=0; i <coplets.getLength(); i++) {
1450                            copletNode = (Element JavaDoc)coplets.item(i);
1451                            oldNumber = copletNode.getAttributeNS(null, "number");
1452                            copletId = copletNode.getAttributeNS(null, "id");
1453                            statusNode = (Element JavaDoc)DOMUtil.getSingleNode(delta, "status-profile/customization/coplet[@id='"+copletId+"' and @number='"+oldNumber+"']", this.xpathProcessor);
1454                            copletNode.setAttributeNS(null, "number", ""+(i+1));
1455                            if (statusNode != null) {
1456                                statusNode.setAttributeNS(null, "number", ""+(i+1));
1457                                copletsChanged = true;
1458                            }
1459                        }
1460                        if (copletsChanged) {
1461                            this.saveUserStatusProfile(originalProfile,
1462                                   this.getConfiguration(), role, id);
1463                        }
1464                    }
1465                }
1466            }
1467        }
1468
1469        // Last part: strip type information
1470
NodeList JavaDoc typeElements = DOMUtil.selectNodeList(delta, "descendant::*[@formpath and @formdescription and @formtype]", this.xpathProcessor);
1471        if (typeElements != null) {
1472            for(int i = 0; i < typeElements.getLength(); i++) {
1473                ((Element JavaDoc)typeElements.item(i)).removeAttributeNS(null, "formpath");
1474                ((Element JavaDoc)typeElements.item(i)).removeAttributeNS(null, "formdescription");
1475                ((Element JavaDoc)typeElements.item(i)).removeAttributeNS(null, "formtype");
1476            }
1477        }
1478
1479        if (this.getLogger().isDebugEnabled()) {
1480            this.getLogger().debug("END buildProfileDelta delta="+delta);
1481        }
1482        return delta;
1483    }
1484
1485    /**
1486     * Make the difference :-)
1487     */

1488    private void diff(DocumentFragment JavaDoc original,
1489                      DocumentFragment JavaDoc base,
1490                      String JavaDoc path,
1491                      Element JavaDoc deltaElement)
1492    throws SAXException JavaDoc, javax.xml.transform.TransformerException JavaDoc {
1493        // calling method is already synchronized
1494
Element JavaDoc originalRoot = (Element JavaDoc)DOMUtil.getSingleNode(original, path, this.xpathProcessor);
1495        Element JavaDoc baseRoot = (Element JavaDoc)DOMUtil.getSingleNode(base, path, this.xpathProcessor);
1496        if (originalRoot != null && baseRoot != null) {
1497            List JavaDoc nodeStack = new ArrayList JavaDoc();
1498            String JavaDoc name = baseRoot.getNodeName();
1499            name = name.substring(0, name.indexOf("-profile")) + "-delta";
1500            nodeStack.add(originalRoot.getOwnerDocument().createElementNS(null, name));
1501
1502            this.diffNode(baseRoot, originalRoot, nodeStack, deltaElement);
1503        }
1504    }
1505
1506    /**
1507     * Diff one node
1508     */

1509    private void diffNode(Element JavaDoc baseNode,
1510                          Element JavaDoc originalNode,
1511                          List JavaDoc nodeStack,
1512                          Element JavaDoc deltaElement)
1513    throws SAXException JavaDoc, javax.xml.transform.TransformerException JavaDoc {
1514        // calling method is already synchronized
1515
NodeList JavaDoc baseChilds;
1516        NodeList JavaDoc originalChilds;
1517        int i, len;
1518        int m, l;
1519        boolean found;
1520        Node JavaDoc currentOrigNode = null;
1521        Node JavaDoc currentBaseNode = null;
1522
1523        originalChilds = originalNode.getChildNodes();
1524        len = originalChilds.getLength();
1525        baseChilds = baseNode.getChildNodes();
1526        l = baseChilds.getLength();
1527
1528        for(i = 0; i < len; i++) {
1529            currentOrigNode = originalChilds.item(i);
1530            if (currentOrigNode.getNodeType() == Node.ELEMENT_NODE) {
1531
1532                // search the delta node in the profile
1533
m = 0;
1534                found = false;
1535                while (!found && m < l) {
1536                    currentBaseNode = baseChilds.item(m);
1537                    if (currentBaseNode.getNodeType() == Node.ELEMENT_NODE
1538                        && currentBaseNode.getNodeName().equals(currentOrigNode.getNodeName()) ) {
1539
1540                        // now we have found a node with the same name
1541
// next: the attributes must match also
1542
found = this.compareAttributes(currentBaseNode, currentOrigNode);
1543                    }
1544                    if (!found) m++;
1545                }
1546
1547                if (found) {
1548                    // do we have elements as children or text?
1549
currentOrigNode.normalize();
1550                    if (currentOrigNode.hasChildNodes()) {
1551
1552                        // do a recursive call for sub elements
1553
nodeStack.add(currentOrigNode);
1554                        this.diffNode((Element JavaDoc)currentBaseNode,
1555                                      (Element JavaDoc)currentOrigNode,
1556                                      nodeStack,
1557                                      deltaElement);
1558
1559                        // and now compare the text nodes
1560
String JavaDoc baseString = DOMUtil.getValueOfNode(currentBaseNode, "").trim();
1561                        String JavaDoc originalString = DOMUtil.getValueOfNode(currentOrigNode, "").trim();
1562
1563                        if (!baseString.equals(originalString)) {
1564                            // this is the tricky part:
1565
// we have to process all nodes on the stack
1566
// and insert them in the deltaElement
1567
Element JavaDoc currentElement;
1568                            Element JavaDoc contextElement = deltaElement;
1569                            NodeList JavaDoc possibleChilds;
1570                            boolean foundChild;
1571                            int cIndex;
1572
1573                            for(int p = 0; p < nodeStack.size(); p++) {
1574                                currentElement = (Element JavaDoc)nodeStack.get(p);
1575                                possibleChilds = DOMUtil.getNodeListFromPath(contextElement, new String JavaDoc[] {currentElement.getNodeName()});
1576                                foundChild = false;
1577                                cIndex = 0;
1578                                if (possibleChilds != null) {
1579                                    while (!foundChild && cIndex < possibleChilds.getLength()) {
1580                                        foundChild = this.compareAttributes(currentElement, possibleChilds.item(cIndex));
1581                                        if (!foundChild) cIndex++;
1582                                    }
1583                                }
1584                                if (foundChild) {
1585                                    contextElement = (Element JavaDoc)possibleChilds.item(cIndex);
1586                                } else {
1587                                    currentElement = (Element JavaDoc)currentElement.cloneNode(false);
1588                                    contextElement.appendChild(currentElement);
1589                                    contextElement = currentElement;
1590                                }
1591                            }
1592                            // now add the text
1593
contextElement.appendChild(contextElement.getOwnerDocument().createTextNode(originalString));
1594                        }
1595
1596                        nodeStack.remove(nodeStack.size()-1);
1597                    }
1598                }
1599            }
1600
1601        }
1602
1603    }
1604
1605    /* (non-Javadoc)
1606     * @see org.apache.cocoon.webapps.portal.components.PortalManager#getProfileID(java.lang.String, java.lang.String, java.lang.String, boolean)
1607     */

1608    public String JavaDoc getProfileID(String JavaDoc type,
1609                                String JavaDoc role,
1610                                String JavaDoc id,
1611                                boolean adminProfile)
1612    throws ProcessingException {
1613        // No sync required
1614
this.setup();
1615        StringBuffer JavaDoc key = new StringBuffer JavaDoc((adminProfile ? "aprofile:" : "uprofile:"));
1616        RequestState reqstate = this.getRequestState();
1617        key.append(reqstate.getHandlerName())
1618           .append('|')
1619           .append(reqstate.getApplicationName())
1620           .append(':')
1621           .append(type);
1622
1623        if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ROLE)
1624            || type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID)) {
1625            role = XMLUtil.encode(role);
1626            key.append('_').append(role.length()).append('_').append(role);
1627        }
1628        if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID)) {
1629            id = XMLUtil.encode(id);
1630            key.append('_').append(id);
1631        }
1632        return key.toString();
1633    }
1634
1635    /**
1636     * Get the profile role from the key
1637     */

1638    private boolean getIsAdminProfile(String JavaDoc profileID) {
1639        // No sync required
1640
return profileID.startsWith("a");
1641    }
1642
1643    /**
1644     * Get the profile role from the key
1645     */

1646    private String JavaDoc getRole(String JavaDoc profileID) {
1647        // No sync required
1648
profileID = XMLUtil.decode(profileID);
1649        int pos = profileID.indexOf('_');
1650        if (pos == -1) {
1651            return null;
1652        } else {
1653            String JavaDoc lastPart = profileID.substring(pos+1);
1654            pos = lastPart.indexOf('_');
1655            if (pos == -1) return null;
1656            int len = new Integer JavaDoc(lastPart.substring(0, pos)).intValue();
1657            lastPart = lastPart.substring(pos+1, pos+1+len);
1658            return lastPart;
1659        }
1660    }
1661
1662    /**
1663     * Get the profile ID from the key
1664     */

1665    private String JavaDoc getID(String JavaDoc profileID) {
1666        // No sync required
1667
profileID = XMLUtil.decode(profileID);
1668        int pos = profileID.indexOf('_');
1669        if (pos == -1) {
1670            return null;
1671        } else {
1672            String JavaDoc lastPart = profileID.substring(pos+1);
1673            pos = lastPart.indexOf('_');
1674            if (pos == -1) {
1675                return null;
1676            } else {
1677                lastPart = lastPart.substring(pos+1);
1678                pos = lastPart.indexOf('_');
1679                if (pos == -1) {
1680                    return null;
1681                } else {
1682                    return lastPart.substring(pos+1);
1683                }
1684            }
1685        }
1686    }
1687
1688    /**
1689     * Get the profile type from the key
1690     */

1691    private String JavaDoc getType(String JavaDoc profileID) {
1692        // No sync required
1693
profileID = XMLUtil.decode(profileID);
1694        int endPos = profileID.indexOf('_');
1695        if (endPos == -1) {
1696            int startPos = profileID.lastIndexOf(':');
1697            return profileID.substring(startPos+1);
1698        } else {
1699            int startPos = profileID.lastIndexOf(':', endPos);
1700            return profileID.substring(startPos+1, endPos);
1701        }
1702    }
1703
1704    /**
1705     * Store the profil
1706     */

1707    private void storeProfile(String JavaDoc profileID,
1708                              Map JavaDoc profile)
1709    throws ProcessingException {
1710        // synchronized
1711
if (this.getLogger().isDebugEnabled()) {
1712            this.getLogger().debug("BEGIN storeProfile id="+profileID+", profile="+profile);
1713        }
1714
1715        Session session = this.getSessionManager().getSession(true);
1716        synchronized(session) {
1717            session.setAttribute(profileID, profile);
1718        }
1719
1720        if (this.getLogger().isDebugEnabled()) {
1721            this.getLogger().debug("END storeProfile");
1722        }
1723    }
1724
1725    /* (non-Javadoc)
1726     * @see org.apache.cocoon.webapps.portal.components.PortalManager#retrieveProfile(java.lang.String)
1727     */

1728    public Map JavaDoc retrieveProfile(String JavaDoc profileID)
1729    throws ProcessingException {
1730        // synchronized
1731
if (this.getLogger().isDebugEnabled()) {
1732            this.getLogger().debug("BEGIN retrieveProfile id="+profileID);
1733        }
1734        this.setup();
1735        Session session = this.getSessionManager().getSession(true);
1736        Map JavaDoc result;
1737        synchronized(session) {
1738            result = (Map JavaDoc)session.getAttribute(profileID);
1739        }
1740
1741        if (this.getLogger().isDebugEnabled()) {
1742            this.getLogger().debug("END retrieveProfile profile="+(result != null ? "**PROFILE**" : "null"));
1743        }
1744
1745        return result;
1746    }
1747
1748    /**
1749     * Cache the profile (if cache is turned on)
1750     */

1751    private void cacheProfile(String JavaDoc profileID,
1752                              Map JavaDoc profile,
1753                              Map JavaDoc configuration) {
1754        // synchronized
1755
if (this.getLogger().isDebugEnabled()) {
1756            this.getLogger().debug("BEGIN cacheProfile id="+profileID+", profile="+profile);
1757        }
1758        try {
1759            if (configuration != null && !this.getIsAdminProfile(profileID)) {
1760                String JavaDoc storePrefix = (String JavaDoc)configuration.get(PortalConstants.CONF_PROFILE_CACHE);
1761                if (storePrefix != null) {
1762                    String JavaDoc key = profileID.substring(1);
1763                    this.getProfileStore().store(key, profile);
1764                }
1765            }
1766        } catch (Exception JavaDoc local) {
1767            this.getLogger().warn("Caching Profile failed.", local);
1768            // local exceptions are ignored
1769
// we dont want to get an exception response due to cache problems
1770
}
1771        if (this.getLogger().isDebugEnabled()) {
1772            this.getLogger().debug("END cacheProfile");
1773        }
1774    }
1775
1776    /**
1777     * Retrieve the cached profil if available
1778     */

1779    private Map JavaDoc getCachedProfile(String JavaDoc profileID, Map JavaDoc configuration) {
1780        // synchronized
1781
if (this.getLogger().isDebugEnabled()) {
1782            this.getLogger().debug("BEGIN getCachedProfile id="+profileID);
1783        }
1784
1785        Map JavaDoc result = null;
1786
1787        try {
1788            if (configuration != null && !this.getIsAdminProfile(profileID)) {
1789                final String JavaDoc storePrefix = (String JavaDoc)configuration.get(PortalConstants.CONF_PROFILE_CACHE);
1790                if (storePrefix != null) {
1791                    final String JavaDoc key = profileID.substring(1);
1792                    final Store store = this.getProfileStore();
1793                    if (store.containsKey(key)) {
1794                        result = (Map JavaDoc)store.get(key);
1795                    }
1796                }
1797            }
1798        } catch (Exception JavaDoc local) {
1799            // local exceptions are ignored
1800
// we dont want to get an exception response due to cache problems
1801
this.getLogger().warn("Getting cached Profile failed.", local);
1802            result = null;
1803        }
1804
1805        if (this.getLogger().isDebugEnabled()) {
1806            this.getLogger().debug("END getCachedProfile profile="+(result != null ? "**PROFILE**" : "null"));
1807        }
1808        return result;
1809    }
1810
1811    /**
1812     * Clean up the cache, if the global profile was saved, delete all role and user profiles.
1813     * If a role profile was saved delete all user profiles. If the basic profile was
1814     * saved delete all profiles.
1815     */

1816    private void cleanUpCache(String JavaDoc type, String JavaDoc role, Map JavaDoc configuration)
1817    throws ProcessingException {
1818        if (this.getLogger().isDebugEnabled()) {
1819            this.getLogger().debug("BEGIN cleanUpCache type="+type+", role="+role+", config="+configuration);
1820        }
1821        if (configuration != null
1822            && type != null
1823            && !type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID)) {
1824            String JavaDoc storePrefix = (String JavaDoc)configuration.get(PortalConstants.CONF_PROFILE_CACHE);
1825            if (storePrefix != null) {
1826                Store store = this.getProfileStore();
1827                Enumeration JavaDoc keys = store.keys();
1828                String JavaDoc currentKey;
1829                String JavaDoc deleteGlobal = null;
1830                String JavaDoc deleteRole = null;
1831                String JavaDoc deleteUser = null;
1832
1833                if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_BASIC) ||
1834                    type.equals(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL)) {
1835                    if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_BASIC)) {
1836                        deleteGlobal = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL, null, null, false).substring(1);
1837                    }
1838                    deleteRole = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL, null, null, false);
1839                    deleteRole = deleteRole.substring(1, deleteRole.lastIndexOf(':')+1) + PortalManagerImpl.BUILDTYPE_VALUE_ROLE;
1840                    deleteUser = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL, null, null, false);
1841                    deleteUser = deleteUser.substring(1, deleteUser.lastIndexOf(':')+1) + PortalManagerImpl.BUILDTYPE_VALUE_ID;
1842                } else { // role
1843
deleteGlobal = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_ROLE, role, null, false).substring(1);
1844                    deleteUser = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_ID, role, "a", false);
1845                    deleteUser = deleteUser.substring(1, deleteUser.length()-1);
1846                }
1847
1848                while (keys.hasMoreElements()) {
1849                    Object JavaDoc k = keys.nextElement();
1850                    if ( k instanceof String JavaDoc ) {
1851                        currentKey = (String JavaDoc)k;
1852                        if (deleteGlobal != null && currentKey.equals(deleteGlobal)) {
1853                            store.remove(currentKey);
1854                        } else if (deleteRole != null && currentKey.startsWith(deleteRole)) {
1855                            store.remove(currentKey);
1856                        } else if (deleteUser != null && currentKey.startsWith(deleteUser)) {
1857                            store.remove(currentKey);
1858                        }
1859                    }
1860                }
1861            }
1862        } else if (configuration != null && type == null) {
1863            // clean whole cache
1864
String JavaDoc storePrefix = (String JavaDoc)configuration.get(PortalConstants.CONF_PROFILE_CACHE);
1865            if (storePrefix != null) {
1866                Store store = this.getProfileStore();
1867                Enumeration JavaDoc keys = store.keys();
1868                String JavaDoc currentKey;
1869                String JavaDoc delete;
1870
1871                delete = this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL, null, null, false);
1872                delete = delete.substring(1, delete.lastIndexOf(':') + 1);
1873                while (keys.hasMoreElements()) {
1874                    Object JavaDoc k = keys.nextElement();
1875                    if ( k instanceof String JavaDoc ) {
1876                        currentKey = (String JavaDoc)k;
1877                        if (currentKey.startsWith(delete)) {
1878                            store.remove(currentKey);
1879                        }
1880                    }
1881                }
1882            }
1883        }
1884
1885        if (this.getLogger().isDebugEnabled()) {
1886            this.getLogger().debug("END cleanUpCache");
1887        }
1888    }
1889
1890    /**
1891     * Build the run profil and store it in the <code>profileMap</code>.
1892     */

1893    private void buildRunProfile(Map JavaDoc profileMap,
1894                                 SessionContext context,
1895                                 DocumentFragment JavaDoc baseProfile)
1896    throws ProcessingException, javax.xml.transform.TransformerException JavaDoc {
1897        // calling method is synced
1898
if (this.getLogger().isDebugEnabled()) {
1899            this.getLogger().debug("BEGIN buildRunProfile context="+context+", profile="+baseProfile);
1900        }
1901
1902        // The map containing the coplets which appear on each medium
1903
Map JavaDoc defaultCoplets = new HashMap JavaDoc(20, 5);
1904        // The map containing for each media type a map with coplets which
1905
// appear only for the given media
1906
Map JavaDoc mediaCoplets = new HashMap JavaDoc(5, 2);
1907
1908        profileMap.put(PortalConstants.PROFILE_DEFAULT_COPLETS, defaultCoplets);
1909        profileMap.put(PortalConstants.PROFILE_MEDIA_COPLETS, mediaCoplets);
1910
1911        // get AuthenticationManager instance
1912
String JavaDoc[] types = this.getMediaManager().getMediaTypes();
1913        Map JavaDoc mediaMap;
1914        for(int i = 0; i < types.length; i++) {
1915            mediaCoplets.put(types[i], new HashMap JavaDoc(5, 3));
1916        }
1917
1918        // build misc nodes
1919
Node JavaDoc[] miscNodes = new Node JavaDoc[13];
1920        miscNodes[PortalConstants.PROFILE_MISC_HEADER_NODE] = DOMUtil.getFirstNodeFromPath(baseProfile, new String JavaDoc[] {"profile","layout-profile","portal","header","exists"}, false);
1921        miscNodes[PortalConstants.PROFILE_MISC_FOOTER_NODE] = DOMUtil.getFirstNodeFromPath(baseProfile, new String JavaDoc[] {"profile","layout-profile","portal","footer","exists"}, false);
1922        miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE] = DOMUtil.getFirstNodeFromPath(baseProfile, new String JavaDoc[] {"profile","portal-profile","content","header"}, false);
1923        miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE] = DOMUtil.getFirstNodeFromPath(baseProfile, new String JavaDoc[] {"profile","portal-profile","content","footer"}, false);
1924        miscNodes[PortalConstants.PROFILE_MISC_COLUMNS_NODE]= DOMUtil.getFirstNodeFromPath(baseProfile, new String JavaDoc[] {"profile","layout-profile","portal","columns","number"}, false);
1925        miscNodes[PortalConstants.PROFILE_MISC_MESSAGES_NODE]= DOMUtil.getFirstNodeFromPath(baseProfile, new String JavaDoc[] {"profile","personal-profile","messages"}, false);
1926        for(int i = 1; i <= PortalConstants.MAX_COLUMNS; i++) {
1927            miscNodes[7 + i] = DOMUtil.getSingleNode(baseProfile,
1928                "profile/portal-profile/content/column[@position='"+i+"']", this.xpathProcessor);
1929        }
1930
1931        profileMap.put(PortalConstants.PROFILE_MISC_POINTER, miscNodes);
1932
1933        // build coplet configs
1934
NodeList JavaDoc coplets;
1935        int i, l;
1936        Element JavaDoc configElement;
1937        String JavaDoc copletID;
1938        String JavaDoc copletMedia;
1939
1940        coplets = DOMUtil.getNodeListFromPath(baseProfile, new String JavaDoc[] {"profile","coplets-profile","coplets","coplet"});
1941
1942        if (coplets != null) {
1943
1944            l = coplets.getLength();
1945            for(i = 0; i < l; i++) {
1946                configElement = (Element JavaDoc)coplets.item(i);
1947                if (DOMUtil.getValueAsBooleanOf(configElement, "configuration/active", this.xpathProcessor)) {
1948
1949                    copletID = configElement.getAttributeNS(null, "id");
1950                    if (configElement.hasAttributeNS(null, "media")) {
1951                        copletMedia = configElement.getAttributeNS(null, "media");
1952                        mediaMap = (Map JavaDoc)mediaCoplets.get(copletMedia);
1953                        if (mediaMap != null) {
1954                            mediaMap.put(copletID, configElement);
1955                        }
1956                    } else {
1957                        copletMedia = null;
1958                        defaultCoplets.put(copletID, configElement);
1959                    }
1960
1961                    // Now: add the coplet if mandatory and missing
1962
if (DOMUtil.getValueAsBooleanOf(configElement, "configuration/mandatory", this.xpathProcessor)) {
1963                        // get all coplet instances
1964
NodeList JavaDoc copletElements;
1965
1966                        // the next is crap, but it works....
1967
// search all coplets (columns, header, footer)
1968
if (copletMedia == null) {
1969                            copletElements = DOMUtil.selectNodeList(baseProfile,
1970                                "profile/portal-profile/content/column/coplets/coplet[@id='"+copletID+"' and not(@media)]", this.xpathProcessor);
1971                        } else {
1972                            copletElements = DOMUtil.selectNodeList(baseProfile,
1973                                "profile/portal-profile/content/column/coplets/coplet[@id='"+copletID+"' and media='"+copletMedia+"']", this.xpathProcessor);
1974                        }
1975
1976                        if (copletElements == null || copletElements.getLength() == 0) {
1977                            if (copletMedia == null) {
1978                                copletElements = DOMUtil.selectNodeList(baseProfile,
1979                                   "profile/portal-profile/content/header/coplet[@id='"+copletID+"' and not(@media)]", this.xpathProcessor);
1980                            } else {
1981                                copletElements = DOMUtil.selectNodeList(baseProfile,
1982                                   "profile/portal-profile/content/header/coplet[@id='"+copletID+"' and media='"+copletMedia+"']", this.xpathProcessor);
1983                            }
1984                        }
1985
1986                        if (copletElements == null || copletElements.getLength() == 0) {
1987                            if (copletMedia == null) {
1988                                copletElements = DOMUtil.selectNodeList(baseProfile,
1989                                   "profile/portal-profile/content/footer/coplet[@id='"+copletID+"' and not(@media)]", this.xpathProcessor);
1990                            } else {
1991                                copletElements = DOMUtil.selectNodeList(baseProfile,
1992                                   "profile/portal-profile/content/footer/coplet[@id='"+copletID+"' and media='"+copletMedia+"']", this.xpathProcessor);
1993                            }
1994                        }
1995
1996                        if (copletElements == null || copletElements.getLength() == 0) {
1997                            // mandatory coplet is not configured, so add it to the first column
1998
Node JavaDoc content = DOMUtil.getSingleNode(baseProfile,
1999                                  "profile/portal-profile/content/column[@position='1']/coplets", this.xpathProcessor);
2000                            if (content == null)
2001                                throw new ProcessingException("Element not found: portal-profile/content/column/coplets");
2002                            Element JavaDoc el = content.getOwnerDocument().createElementNS(null, "coplet");
2003                            el.setAttributeNS(null, "id", copletID);
2004                            if (copletMedia != null) {
2005                                el.setAttributeNS(null, "media", copletMedia);
2006                            }
2007                            // Set position attribute
2008
NodeList JavaDoc childs = DOMUtil.getNodeListFromPath(content, new String JavaDoc[] {"coplet"});
2009                            int childsCount = (childs == null ? 0 : childs.getLength());
2010                            el.setAttributeNS(null, "position", ""+(childsCount+1));
2011                            Text JavaDoc t;
2012                            content.appendChild(el);
2013                            content = el;
2014                            el = content.getOwnerDocument().createElementNS(null, "status");
2015                            content.appendChild(el);
2016                            content = el;
2017                            el = content.getOwnerDocument().createElementNS(null, "visible");
2018                            content.appendChild(el);
2019                            content = el;
2020                            t = content.getOwnerDocument().createTextNode("true");
2021                            content.appendChild(t);
2022                        } else {
2023                            // is any of them visible?
2024
boolean found;
2025                            boolean origVisible = DOMUtil.getValueAsBooleanOf(configElement, "status/visible", this.xpathProcessor);
2026                            int si, sl;
2027                            sl = copletElements.getLength();
2028                            si = 0;
2029                            found = false;
2030                            while (si < sl && !found) {
2031                                found = DOMUtil.getValueAsBooleanOf(copletElements.item(si),
2032                                           "status/visible", origVisible, this.xpathProcessor);
2033                                si++;
2034                            }
2035                            if (!found) {
2036                                // set first to visible
2037
// first: is status node available
2038
Node JavaDoc statusElem = DOMUtil.getFirstNodeFromPath(copletElements.item(0), new String JavaDoc[] {"status"}, false);
2039                                if (statusElem == null) {
2040                                    statusElem = copletElements.item(0).getOwnerDocument().createElementNS(null, "status");
2041                                    copletElements.item(0).appendChild(statusElem);
2042                                }
2043                                // second: is visible node available
2044
Node JavaDoc visibleElem = DOMUtil.getFirstNodeFromPath(statusElem, new String JavaDoc[] {"visible"}, false);
2045                                if (visibleElem == null) {
2046                                    visibleElem = statusElem.getOwnerDocument().createElementNS(null, "visible");
2047                                    statusElem.appendChild(visibleElem);
2048                                }
2049                                // remove old childs
2050
while (visibleElem.hasChildNodes()) {
2051                                    visibleElem.removeChild(visibleElem.getFirstChild());
2052                                }
2053                                visibleElem.appendChild(statusElem.getOwnerDocument().createTextNode("true"));
2054                            }
2055                        }
2056                    }
2057                }
2058            }
2059        }
2060
2061        // Numerate all coplets by adding an attribute number with a unique value
2062
// and put them into the corresponding maps.
2063
// update the status section of the coplet: Only the values of the coplet
2064
// configuration are allowed. Not less and not more!
2065
// All coplets are required to have
2066
// the number attribute! So this is only a compatibility function
2067
// which adds the first time the number to the coplets
2068
// If the number attribute is available, the node with the highest
2069
// number is searched
2070
NodeList JavaDoc copletElements;
2071        int number = 0;
2072        Element JavaDoc content = (Element JavaDoc)DOMUtil.getFirstNodeFromPath(baseProfile,
2073                       new String JavaDoc[] {"profile","portal-profile","content"}, false);
2074        Element JavaDoc currentCoplet;
2075        NodeList JavaDoc statusConfigList;
2076        NodeList JavaDoc statusCopletList;
2077        Element JavaDoc statusCopletElement;
2078        int list_index, list_length;
2079        Node JavaDoc currentStatus;
2080        int highestCopletNumber = -1;
2081
2082        for(i = 0; i < 7; i++) {
2083            if (i == 0) {
2084                copletElements = DOMUtil.getNodeListFromPath(content,
2085                   new String JavaDoc[] {"header","coplet"});
2086            } else if (i == 1) {
2087                copletElements = DOMUtil.getNodeListFromPath(content,
2088                   new String JavaDoc[] {"footer","coplet"});
2089            } else {
2090                copletElements = DOMUtil.selectNodeList(content,
2091                   "column[@position='"+(i-1)+"']/coplets/coplet", this.xpathProcessor);
2092            }
2093            if (copletElements != null && copletElements.getLength() > 0) {
2094                Element JavaDoc[] list = new Element JavaDoc[copletElements.getLength()];
2095                for(int index = 0; index < copletElements.getLength(); index++) {
2096                    list[index] = (Element JavaDoc)copletElements.item(index);
2097                }
2098
2099                for(int index = 0; index < list.length; index++) {
2100                    // get coplet element
2101
currentCoplet = list[index];
2102
2103                    String JavaDoc numberValue = currentCoplet.getAttributeNS(null, "number");
2104                    if (numberValue == null || numberValue.equals("")) {
2105                        // create unique number attribute
2106
currentCoplet.setAttributeNS(null, "number", ""+number);
2107                        miscNodes[PortalConstants.PROFILE_MISC_LAST_COPLET_NODE] = currentCoplet;
2108                        number++;
2109                    } else {
2110                        int currentNumber = new Integer JavaDoc(numberValue).intValue();
2111                        if (currentNumber > highestCopletNumber) {
2112                            highestCopletNumber = currentNumber;
2113                            number = highestCopletNumber+1;
2114                            miscNodes[PortalConstants.PROFILE_MISC_LAST_COPLET_NODE] = currentCoplet;
2115                        }
2116                    }
2117                    // update status
2118
configElement = this.getCopletConfiguration(currentCoplet.getAttributeNS(null, "id"),
2119                                                      defaultCoplets,
2120                                                      mediaCoplets);
2121                    if (configElement != null) {
2122                        statusCopletElement = (Element JavaDoc)DOMUtil.selectSingleNode(configElement, "status", this.xpathProcessor);
2123                        statusConfigList = DOMUtil.selectNodeList(statusCopletElement, "*", this.xpathProcessor);
2124                        statusCopletList = DOMUtil.selectNodeList(currentCoplet, "status/*", this.xpathProcessor);
2125                        // first test if each status is included in the config
2126
if (statusCopletList != null) {
2127                            list_length = statusCopletList.getLength();
2128                            for(list_index = list_length-1; list_index >= 0; list_index--) {
2129                                currentStatus = statusCopletList.item(list_index);
2130                                if (currentStatus.getNodeType() == Node.ELEMENT_NODE) {
2131                                    if (DOMUtil.getFirstNodeFromPath(configElement, new String JavaDoc[] {"status", currentStatus.getNodeName()}, false) == null) {
2132                                        currentStatus.getParentNode().removeChild(currentStatus);
2133                                    }
2134                                }
2135                            }
2136                        }
2137                        // second, test if each status attribute of the config is included
2138
if (statusConfigList != null) {
2139                            list_length = statusConfigList.getLength();
2140                            for(list_index = 0; list_index < list_length; list_index++) {
2141                                currentStatus = statusConfigList.item(list_index);
2142                                if (currentStatus.getNodeType() == Node.ELEMENT_NODE) {
2143                                    if (DOMUtil.getFirstNodeFromPath(statusCopletElement, new String JavaDoc[] {currentStatus.getNodeName()}, false) == null) {
2144                                        // create a new element
2145
statusCopletElement.appendChild(statusCopletElement.getOwnerDocument().importNode(currentStatus, true));
2146                                    }
2147                                }
2148                            }
2149                        }
2150                    } else {
2151                        // coplet not in configuration
2152
// adopt position of following coplets and then remove
2153
String JavaDoc posAttr = currentCoplet.getAttributeNS(null, "position");
2154                        NodeList JavaDoc followUps = DOMUtil.selectNodeList(currentCoplet.getParentNode(), "coplet[@position > '"+posAttr+"']", this.xpathProcessor);
2155                        if (followUps != null) {
2156                            int value;
2157                            for(int iq = 0; iq < followUps.getLength(); iq++) {
2158                                value = new Integer JavaDoc(((Element JavaDoc)followUps.item(iq)).getAttributeNS(null, "position")).intValue();
2159                                value -= 1;
2160                                ((Element JavaDoc)followUps.item(iq)).setAttributeNS(null, "position", "" + value);
2161                            }
2162                        }
2163                        currentCoplet.getParentNode().removeChild(currentCoplet);
2164                    }
2165                }
2166            }
2167        }
2168
2169        if (this.getLogger().isDebugEnabled()) {
2170            this.getLogger().debug("END buildRunProfile");
2171        }
2172    }
2173
2174    /**
2175     * Add the type information to the profile and do some type checkings
2176     */

2177    private void buildTypeProfile(Map JavaDoc theProfile,
2178                                  SessionContext context,
2179                                  DocumentFragment JavaDoc baseProfile)
2180    throws javax.xml.transform.TransformerException JavaDoc {
2181        // calling method is synced
2182
if (this.getLogger().isDebugEnabled()) {
2183            this.getLogger().debug("BEGIN buildTypeProfile context="+context+", profile="+baseProfile);
2184        }
2185        List JavaDoc list = new ArrayList JavaDoc(25);
2186        List JavaDoc confList = new ArrayList JavaDoc(25);
2187
2188        theProfile.put(PortalConstants.PROFILE_TYPE_PATHS, list);
2189        theProfile.put(PortalConstants.PROFILE_TYPE_CONF_PATHS, confList);
2190
2191        Element JavaDoc typeElement;
2192
2193        typeElement = (Element JavaDoc)DOMUtil.getFirstNodeFromPath(baseProfile, new String JavaDoc[] {"profile","type-profile","elements"}, false);
2194        if (typeElement != null) {
2195            if (typeElement.hasChildNodes())
2196                this.addTypePath(list, typeElement.getChildNodes(), "profile");
2197
2198            // now we have the list with the xpaths
2199
this.setTypeInfo(baseProfile, list, null);
2200
2201            // build the conf paths
2202
int i, l, pos;
2203            String JavaDoc current;
2204
2205            l = list.size();
2206            for(i = 0; i < l; i++) {
2207                current = (String JavaDoc)list.get(i);
2208
2209                // now the path has to be changed: the new attributes must be included
2210
pos = current.lastIndexOf('/');
2211                current = current.substring(0, pos);
2212
2213                pos = current.lastIndexOf('[');
2214                if (current.substring(pos+1).equals("not(@*)]")) {
2215                    current = current.substring(0, pos+1);
2216                } else {
2217                    current = current.substring(0, current.length()-1) + " and ";
2218                }
2219                current += "@formtype and @formpath and @formdescription]";
2220                confList.add(current);
2221            }
2222
2223        }
2224
2225        // and now the type checking part:
2226
//
2227
// If the default layout has changed the number of columns and the current
2228
// user (or role) is not allowed to change this, we have to adjust the
2229
// profile. Otherwise the current number of columns has to be stored
2230
// into the profile layout part.
2231
Element JavaDoc layoutColumnsNode = (Element JavaDoc)DOMUtil.getFirstNodeFromPath(baseProfile, new String JavaDoc[] {"profile","layout-profile","portal","columns","number"}, false);
2232        String JavaDoc layoutValue = DOMUtil.getValueOfNode(layoutColumnsNode);
2233        int layoutColumns = 0;
2234        if (layoutValue != null && new Integer JavaDoc(layoutValue).intValue() > 0) {
2235            layoutColumns = new Integer JavaDoc(layoutValue).intValue();
2236        }
2237        NodeList JavaDoc columnNodes = DOMUtil.selectNodeList(baseProfile, "profile/portal-profile/content/column[@position]", this.xpathProcessor);
2238        int columns = columnNodes.getLength();
2239        if (columns != layoutColumns) {
2240            if (layoutColumnsNode.hasAttributeNS(null, "formtype")) {
2241                DOMUtil.setValueOfNode(layoutColumnsNode, ""+columns);
2242            } else {
2243                this.changeColumns(baseProfile,
2244                                   columns,
2245                                   layoutColumns,
2246                                   (Node JavaDoc[])theProfile.get(PortalConstants.PROFILE_MISC_POINTER));
2247                this.setTypeInfo(baseProfile,
2248                                 (List JavaDoc)theProfile.get(PortalConstants.PROFILE_TYPE_PATHS),
2249                                 (List JavaDoc)theProfile.get(PortalConstants.PROFILE_TYPE_CONF_PATHS));
2250            }
2251        }
2252
2253        if (this.getLogger().isDebugEnabled()) {
2254            this.getLogger().debug("END buildTypeProfile");
2255        }
2256    }
2257
2258    /**
2259     * Set the tpe information
2260     */

2261    private void setTypeInfo(DocumentFragment JavaDoc baseProfile, List JavaDoc paths, List JavaDoc confPaths)
2262    throws javax.xml.transform.TransformerException JavaDoc {
2263        // calling method is synced
2264
if (this.getLogger().isDebugEnabled()) {
2265            this.getLogger().debug("BEGIN setTypeInfo profile="+baseProfile+", paths="+paths);
2266        }
2267        if (baseProfile != null && paths != null) {
2268            int pos;
2269            String JavaDoc currentPath;
2270            String JavaDoc value;
2271            String JavaDoc description;
2272            NodeList JavaDoc nodes;
2273            int nodes_count;
2274            int path_count = paths.size();
2275            Node JavaDoc currentNode;
2276
2277            for(int i = 0; i < path_count; i++) {
2278                currentPath = (String JavaDoc)paths.get(i);
2279                pos = currentPath.lastIndexOf('/');
2280                value = currentPath.substring(pos + 1);
2281                currentPath = currentPath.substring(0, pos);
2282                pos = value.indexOf("|");
2283                if (pos != -1) {
2284                    description = value.substring(pos + 1);
2285                    value = value.substring(0, pos);
2286                } else {
2287                    description = "UNKNOWN";
2288                }
2289
2290                // get all nodes
2291
boolean changed = false;
2292                nodes = DOMUtil.selectNodeList(baseProfile, currentPath, this.xpathProcessor);
2293                if (nodes != null) {
2294                    nodes_count = nodes.getLength();
2295                    for(int m = 0; m < nodes_count; m++) {
2296                        currentNode = nodes.item(m);
2297                        if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
2298                            ((Element JavaDoc)currentNode).setAttributeNS(null, "formtype", value);
2299                            ((Element JavaDoc)currentNode).setAttributeNS(null, "formpath",
2300                                     PortalManagerImpl.REQ_PARAMETER_CONF + '.' + i + '.' + m);
2301                            ((Element JavaDoc)currentNode).setAttributeNS(null, "formdescription", description);
2302                            changed = true;
2303                        }
2304                    }
2305                }
2306                if (changed && confPaths != null) {
2307                    currentPath = (String JavaDoc)confPaths.get(i);
2308                    nodes = DOMUtil.selectNodeList(baseProfile, currentPath, this.xpathProcessor);
2309                    if (nodes != null) {
2310                        nodes_count = nodes.getLength();
2311                        for(int m = 0; m < nodes_count; m++) {
2312                            currentNode = nodes.item(m);
2313                            if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
2314                                ((Element JavaDoc)currentNode).setAttributeNS(null, "formpath",
2315                                     PortalManagerImpl.REQ_PARAMETER_CONF + '.' + i + '.' + m);
2316                            }
2317                        }
2318                    }
2319                }
2320            }
2321        }
2322
2323        if (this.getLogger().isDebugEnabled()) {
2324            this.getLogger().debug("END setTypeInfo");
2325        }
2326    }
2327
2328
2329    /**
2330     * Add the type info to the xpath. This is done recursevly
2331     */

2332    private void addTypePath(List JavaDoc list, NodeList JavaDoc childs, String JavaDoc path) {
2333        // calling method is synced
2334
int i, l;
2335        Element JavaDoc current;
2336        StringBuffer JavaDoc newPath;
2337
2338        l = childs.getLength();
2339        for(i = 0; i < l; i++) {
2340            if (childs.item(i).getNodeType() == Node.ELEMENT_NODE) {
2341                current = (Element JavaDoc)childs.item(i);
2342                newPath = new StringBuffer JavaDoc(path);
2343                newPath.append('/').append(current.getNodeName());
2344                if (current.hasAttributes()) {
2345                    NamedNodeMap JavaDoc nnm = current.getAttributes();
2346                    int ia, la;
2347                    boolean first = true;
2348                    StringBuffer JavaDoc expression = new StringBuffer JavaDoc();
2349                    la = nnm.getLength();
2350                    newPath.append('[');
2351                    for(ia = 0; ia < la; ia++) {
2352                        if (!nnm.item(ia).getNodeName().equals("type")
2353                            && !nnm.item(ia).getNodeName().equals("description")) {
2354                            if (!first) expression.append(" and ");
2355                            if (!nnm.item(ia).getNodeValue().equals("*")) {
2356                                expression.append('@')
2357                                  .append(nnm.item(ia).getNodeName())
2358                                  .append("='")
2359                                  .append(nnm.item(ia).getNodeValue())
2360                                  .append("'");
2361                            } else {
2362                                expression.append('@').append(nnm.item(ia).getNodeName());
2363                            }
2364                            first = false;
2365                        }
2366                    }
2367                    if (first) {
2368                        newPath.append("not(@*)");
2369                    } else {
2370                        newPath.append(expression);
2371                    }
2372                    newPath.append(']');
2373                } else {
2374                    newPath.append("[not(@*)]");
2375                }
2376                if (current.getAttributeNS(null, "type").length() > 0) {
2377                    list.add(newPath.toString() + '/' + current.getAttributeNS(null, "type") + '|' + current.getAttributeNS(null, "description"));
2378                } else {
2379                    if (current.hasChildNodes()) {
2380                        this.addTypePath(list, current.getChildNodes(), newPath.toString());
2381                    }
2382                }
2383            }
2384        }
2385    }
2386
2387    /**
2388     * Build the Map with the portal layouts
2389     */

2390    private Map JavaDoc buildPortalLayouts(SessionContext context,
2391                                 DocumentFragment JavaDoc baseProfile)
2392    throws ProcessingException, javax.xml.transform.TransformerException JavaDoc {
2393        // calling method is synced
2394
if (this.getLogger().isDebugEnabled()) {
2395            this.getLogger().debug("BEGIN buildPortalLayouts context="+context+", profile="+baseProfile);
2396        }
2397        Map JavaDoc layouts = new HashMap JavaDoc(5, 2);
2398        Element JavaDoc defLayout = (Element JavaDoc)DOMUtil.getSingleNode(baseProfile,
2399                        "profile/layout-profile/portal/layouts/layout[not(@*)]", this.xpathProcessor);
2400        Node JavaDoc currentLayout;
2401        String JavaDoc[] types = this.getMediaManager().getMediaTypes();
2402
2403        for(int i = 0; i < types.length; i++) {
2404             currentLayout = DOMUtil.getSingleNode(baseProfile,
2405               "profile/layout-profile/portal/layouts/layout[media='"+types[i]+"']", this.xpathProcessor);
2406             layouts.put(types[i], (currentLayout == null ? defLayout : currentLayout));
2407        }
2408
2409        if (this.getLogger().isDebugEnabled()) {
2410            this.getLogger().debug("END buildPortalLayouts layouts="+layouts);
2411        }
2412        return layouts;
2413    }
2414
2415    /**
2416     * Build the Map with the coplet layouts
2417     */

2418    private Map JavaDoc buildcopleyLayouts(SessionContext context,
2419                                 DocumentFragment JavaDoc baseProfile)
2420    throws ProcessingException, javax.xml.transform.TransformerException JavaDoc {
2421        // calling method is synced
2422
if (this.getLogger().isDebugEnabled()) {
2423            this.getLogger().debug("BEGIN buildcopleyLayouts context="+context+", profile="+baseProfile);
2424        }
2425        Map JavaDoc layouts = new HashMap JavaDoc(5, 2);
2426        Element JavaDoc defLayout = (Element JavaDoc)DOMUtil.getSingleNode(baseProfile,
2427                        "profile/layout-profile/coplets/layouts/layout[not(@*)]", this.xpathProcessor);
2428        Node JavaDoc currentLayout;
2429        String JavaDoc[] types = this.getMediaManager().getMediaTypes();
2430
2431        for(int i = 0; i < types.length; i++) {
2432            currentLayout = DOMUtil.getSingleNode(baseProfile,
2433               "profile/layout-profile/coplets/layouts/layout[media='"+types[i]+"']", this.xpathProcessor);
2434           layouts.put(types[i], (currentLayout == null ? defLayout : currentLayout));
2435        }
2436
2437        if (this.getLogger().isDebugEnabled()) {
2438            this.getLogger().debug("END buildcopleyLayouts layouts="+layouts);
2439        }
2440        return layouts;
2441    }
2442
2443    /**
2444     * Import a delta into the profile
2445     */

2446    private void importProfileDelta(Element JavaDoc profileRoot,
2447                                  DocumentFragment JavaDoc delta,
2448                                  String JavaDoc deltaRootTagName,
2449                                  String JavaDoc deltaTag)
2450    throws ProcessingException {
2451        // calling method is synced
2452
if (this.getLogger().isDebugEnabled()) {
2453            this.getLogger().debug("BEGIN importProfileDelta root=" + profileRoot + ", delta=" + delta + ", deltaRoot:" + deltaRootTagName + ", delta: " + deltaTag);
2454        }
2455        Node JavaDoc deltaRoot = null;
2456
2457        deltaRoot = DOMUtil.getFirstNodeFromPath(delta, new String JavaDoc[] {deltaRootTagName, deltaTag}, false);
2458
2459        if (deltaRoot != null) {
2460            // root tag found in delta , now search root tag in profile
2461
String JavaDoc searchName = deltaRoot.getNodeName().substring(0, deltaRoot.getNodeName().lastIndexOf("-delta"));
2462            searchName = searchName + "-profile";
2463
2464            profileRoot = (Element JavaDoc)DOMUtil.getFirstNodeFromPath(profileRoot, new String JavaDoc[] {searchName}, false);
2465            if (profileRoot == null) {
2466                throw new ProcessingException("Importing Delta: Tag " + searchName + " not found in profile.");
2467            }
2468
2469            // now import it
2470
this.importNode(profileRoot, (Element JavaDoc)deltaRoot);
2471        }
2472
2473        if (this.getLogger().isDebugEnabled()) {
2474            this.getLogger().debug("END importProfileDelta");
2475        }
2476    }
2477
2478    /**
2479     * Add the node to the profile (replace an existing one)
2480     */

2481    private void addProfilePart(Element JavaDoc profileRoot,
2482                              DocumentFragment JavaDoc delta,
2483                              String JavaDoc deltaRootTagName,
2484                              String JavaDoc deltaTag)
2485    {
2486        // calling method is synced
2487
if (this.getLogger().isDebugEnabled()) {
2488           this.getLogger().debug("BEGIN addProfilePart root=" + profileRoot + ", delta=" + delta + ", deltaRoot:" + deltaRootTagName + ", delta: " + deltaTag);
2489        }
2490        Node JavaDoc deltaRoot = null;
2491        Node JavaDoc oldNode = null;
2492
2493        if (deltaRootTagName != null) {
2494            deltaRoot = DOMUtil.getFirstNodeFromPath(delta, new String JavaDoc[] {deltaRootTagName, deltaTag}, false);
2495        } else {
2496            deltaRoot = DOMUtil.getFirstNodeFromPath(delta, new String JavaDoc[] {deltaTag}, false);
2497        }
2498
2499        if (deltaRoot != null) {
2500            // root tag found in delta found, now search root tag in profile
2501
oldNode = DOMUtil.getFirstNodeFromPath(profileRoot, new String JavaDoc[] {deltaTag}, false);
2502            if (oldNode == null) {
2503                profileRoot.appendChild(profileRoot.getOwnerDocument().importNode(deltaRoot, true));
2504            } else {
2505                profileRoot.replaceChild(profileRoot.getOwnerDocument().importNode(deltaRoot, true), oldNode);
2506            }
2507        }
2508
2509        if (this.getLogger().isDebugEnabled()) {
2510            this.getLogger().debug("END addProfilePart");
2511        }
2512    }
2513
2514
2515    /**
2516     * This is the hardest part. Incorporting a node into the profile.
2517     * For performance reasons there is now tracing here.
2518     */

2519    private void importNode(Element JavaDoc profile, Element JavaDoc delta) {
2520        // calling method is synced
2521
NodeList JavaDoc profileChilds = null;
2522        NodeList JavaDoc deltaChilds = delta.getChildNodes();
2523        int i, len;
2524        int m, l;
2525        boolean found;
2526        Node JavaDoc currentDelta = null;
2527        Node JavaDoc currentProfile = null;
2528
2529        len = deltaChilds.getLength();
2530        for(i = 0; i < len; i++) {
2531            currentDelta = deltaChilds.item(i);
2532            if (currentDelta.getNodeType() == Node.ELEMENT_NODE) {
2533                // search the delta node in the profile
2534
profileChilds = profile.getChildNodes();
2535                l = profileChilds.getLength();
2536                m = 0;
2537                found = false;
2538                while (!found && m < l) {
2539                    currentProfile = profileChilds.item(m);
2540                    if (currentProfile.getNodeType() == Node.ELEMENT_NODE
2541                        && currentProfile.getNodeName().equals(currentDelta.getNodeName())) {
2542
2543                        // now we have found a node with the same name
2544
// next: the attributes must match also
2545
found = this.compareAttributes(currentProfile, currentDelta);
2546                    }
2547                    if (!found) m++;
2548                }
2549                if (found) {
2550                    // this is not new
2551

2552                    // do we have elements as children or text?
2553
if (currentDelta.hasChildNodes()) {
2554                        currentDelta.normalize();
2555                        currentProfile.normalize();
2556                        // do a recursive call for sub elements
2557
this.importNode((Element JavaDoc)currentProfile, (Element JavaDoc)currentDelta);
2558                        // and now the text nodes: Remove all from the profile and add all
2559
// of the delta
2560
NodeList JavaDoc childs = currentProfile.getChildNodes();
2561                        int index, max;
2562                        max = childs.getLength();
2563                        for(index = max - 1; index >= 0; index--) {
2564                            if (childs.item(index).getNodeType() == Node.TEXT_NODE) {
2565                                currentProfile.removeChild(childs.item(index));
2566                            }
2567                        }
2568                        childs = currentDelta.getChildNodes();
2569                        max = childs.getLength();
2570                        for(index = 0; index < max; index++) {
2571                            if (childs.item(index).getNodeType() == Node.TEXT_NODE) {
2572                                currentProfile.appendChild(currentProfile.getOwnerDocument()
2573                                     .createTextNode(childs.item(index).getNodeValue()));
2574                            }
2575                        }
2576                    }
2577                } else {
2578                    // this is a new node, so it is considered as an old information
2579
// No inserting: profile.appendChild(profile.getOwnerDocument().importNode(currentDelta, true));
2580
}
2581            }
2582
2583        }
2584
2585    }
2586
2587    /**
2588     * Compare Attributes of two nodes. This method returns true only if both
2589     * nodes have the same number of attributes and the same attributes with equal
2590     * values.
2591     * Namespacedefinition nodes are ignored
2592     * BUT: For type handling the attributes <code>formtype</code>,
2593     * <code>formdescription</code> and <code>formpath</code> are ignored!
2594     */

2595    private boolean compareAttributes(Node JavaDoc first, Node JavaDoc second) {
2596        // calling method is synced
2597
NamedNodeMap JavaDoc attr1 = first.getAttributes();
2598        NamedNodeMap JavaDoc attr2 = second.getAttributes();
2599        String JavaDoc value;
2600
2601        if (attr1 == null && attr2 == null) return true;
2602        if (attr1 == null || attr2 == null) return false;
2603        int attr1Len = (attr1 == null ? 0 : attr1.getLength());
2604        int attr2Len = (attr2 == null ? 0 : attr2.getLength());
2605        if (attr1Len > 0) {
2606            if (attr1.getNamedItemNS(null, "formtype") != null) attr1Len--;
2607            if (attr1.getNamedItemNS(null, "formpath") != null) attr1Len--;
2608            if (attr1.getNamedItemNS(null, "formdescription") != null) attr1Len--;
2609            int l = attr1.getLength();
2610            for(int i=0;i<l;i++) {
2611                if (attr1.item(i).getNodeName().startsWith("xmlns:"))
2612                    attr1Len--;
2613            }
2614        }
2615        if (attr2Len > 0) {
2616            if (attr2.getNamedItemNS(null, "formtype") != null) attr2Len--;
2617            if (attr2.getNamedItemNS(null, "formpath") != null) attr2Len--;
2618            if (attr2.getNamedItemNS(null, "formdescription") != null) attr2Len--;
2619            int l = attr2.getLength();
2620            for(int i=0;i<l;i++) {
2621                if (attr2.item(i).getNodeName().startsWith("xmlns:"))
2622                    attr2Len--;
2623            }
2624        }
2625        if (attr1Len != attr2Len) return false;
2626        int i, l;
2627        int m, l2;
2628        i = 0;
2629        l = attr1.getLength();
2630        l2 = attr2.getLength();
2631        boolean ok = true;
2632        // each attribute of first must be in second with the same value
2633
while (i < l && ok) {
2634            value = attr1.item(i).getNodeName();
2635            if (!value.equals("formtype")
2636                && !value.equals("formpath")
2637                && !value.equals("formdescription")
2638                && !value.startsWith("xmlns:")) {
2639                ok = false;
2640                m = 0;
2641                while (m < l2 && !ok) {
2642                    if (attr2.item(m).getNodeName().equals(value)) {
2643                        // same name, same value?
2644
ok = attr1.item(i).getNodeValue().equals(attr2.item(m).getNodeValue());
2645                    }
2646                    m++;
2647                }
2648
2649            }
2650            i++;
2651        }
2652        return ok;
2653    }
2654
2655
2656    /**
2657     * Parse the fragment(tree denoted by the element)
2658     * and include the processed xml in the output
2659     */

2660    private void processCopletList(List JavaDoc copletList,
2661                                   XMLConsumer consumer,
2662                                   String JavaDoc copletNotAvailableMessage,
2663                                   long defaultCopletTimeout)
2664    throws ProcessingException, SAXException JavaDoc, javax.xml.transform.TransformerException JavaDoc {
2665        // calling method is synced
2666
for(int i = 0; i < copletList.size(); i++) {
2667            this.processCoplet((Object JavaDoc[])copletList.get(i),
2668                         consumer, copletNotAvailableMessage, defaultCopletTimeout);
2669        }
2670    }
2671
2672    /**
2673     * Parse the fragment(tree denoted by the element)
2674     * and include the processed xml in the output
2675     */

2676    private void loadCoplets(Element JavaDoc element,
2677                             Map JavaDoc defaultCoplets,
2678                             Map JavaDoc mediaCoplets,
2679                             List JavaDoc copletList,
2680                             boolean parallelCoplets,
2681                             long defaultCopletTimeout,
2682                             Element JavaDoc statusProfile)
2683    throws ProcessingException, javax.xml.transform.TransformerException JavaDoc {
2684        // calling method is synced
2685
// All children, which are coplets are processed, all other tags
2686
// are ignored
2687
if (element.hasChildNodes()) {
2688            NodeList JavaDoc childs = element.getChildNodes();
2689            Node JavaDoc current = null;
2690            int i, l;
2691            l = childs.getLength();
2692            for(i = 0; i < l; i++) {
2693                current = childs.item(i);
2694                if (current.getNodeType() == Node.ELEMENT_NODE
2695                    && current.getNodeName().equals("coplet")) {
2696
2697                    // now we have a coplet
2698
this.loadCoplet((Element JavaDoc)current,
2699                             defaultCoplets,
2700                             mediaCoplets,
2701                             copletList,
2702                             parallelCoplets,
2703                             defaultCopletTimeout,
2704                             statusProfile);
2705                }
2706            }
2707        }
2708    }
2709
2710    /**
2711     * Load a coplet and store the binary output in the list
2712     */

2713    private void loadCoplet(Element JavaDoc element,
2714                            Map JavaDoc defaultCoplets,
2715                            Map JavaDoc mediaCoplets,
2716                            List JavaDoc copletList,
2717                            boolean parallelCoplets,
2718                            long defaultCopletTimeout,
2719                            Element JavaDoc statusProfile)
2720    throws ProcessingException, javax.xml.transform.TransformerException JavaDoc {
2721        // calling method is synced
2722
String JavaDoc copletID = element.getAttributeNS(null, "id");
2723
2724        Element JavaDoc copletConf = this.getCopletConfiguration(copletID, defaultCoplets, mediaCoplets);
2725        if (copletConf != null) {
2726
2727             // first: check visibility
2728
boolean visible = DOMUtil.getValueAsBooleanOf(element,
2729                "status/visible", this.xpathProcessor);
2730            // second: check media
2731
String JavaDoc media = this.getMediaManager().getMediaType();
2732            if (visible && copletConf.hasAttributeNS(null, "media")) {
2733                String JavaDoc copletMedia = copletConf.getAttributeNS(null, "media");
2734                visible = media.equals(copletMedia);
2735            }
2736
2737            if (visible) {
2738
2739                Object JavaDoc[] loadedCoplet = new Object JavaDoc[8];
2740                copletList.add(loadedCoplet);
2741
2742                boolean isCustomizable = DOMUtil.getValueAsBooleanOf(copletConf, "configuration/customizable", false, this.xpathProcessor);
2743                if (isCustomizable) {
2744                    boolean showCustomizePage = DOMUtil.getValueAsBooleanOf(element, "status/customize", false, this.xpathProcessor);
2745                    boolean hasConfig = false;
2746                    if (statusProfile != null) {
2747                        Element JavaDoc customInfo = (Element JavaDoc)DOMUtil.getSingleNode(statusProfile,
2748                              "customization/coplet[@id='"+copletID+"' and @number='"+element.getAttributeNS(null, "number")+"']", this.xpathProcessor);
2749                        hasConfig = (customInfo != null);
2750                    }
2751                    if (showCustomizePage || !hasConfig ) {
2752                        Node JavaDoc node = DOMUtil.selectSingleNode(element, "status/customize", this.xpathProcessor);
2753                        DOMUtil.setValueOfNode(node, "true");
2754                    } else {
2755                        Node JavaDoc node = DOMUtil.selectSingleNode(element, "status/customize", this.xpathProcessor);
2756                        DOMUtil.setValueOfNode(node, "false");
2757                    }
2758                } else {
2759                    Node JavaDoc node = DOMUtil.selectSingleNode(element, "status/customize", this.xpathProcessor);
2760                    DOMUtil.setValueOfNode(node, "false");
2761                }
2762
2763                // Create the parameters for the coplet:
2764
// The <status> part is mapped to parameters
2765
// id, number and media are added
2766
SourceParameters p = DOMUtil.createParameters(DOMUtil.getFirstNodeFromPath(element, new String JavaDoc[] {"status"}, false), null);
2767                p.setSingleParameterValue(PortalConstants.PARAMETER_ID, copletID);
2768                p.setSingleParameterValue(PortalConstants.PARAMETER_NUMBER, element.getAttributeNS(null, "number"));
2769                p.setSingleParameterValue(PortalConstants.PARAMETER_MEDIA, media);
2770                String JavaDoc isPersistent = DOMUtil.getValueOf(copletConf, "configuration/persistent", "false", this.xpathProcessor);
2771                p.setSingleParameterValue(PortalConstants.PARAMETER_PERSISTENT, isPersistent);
2772
2773                // the coplet loading is a tricky part:
2774
// we create an object array containing all information
2775
// for later processing of the coplet
2776
// so the processCoplet() method needs no lookup for information
2777
// again
2778
loadedCoplet[0] = null;
2779                loadedCoplet[1] = copletConf;
2780                loadedCoplet[2] = p;
2781                loadedCoplet[3] = element;
2782                loadedCoplet[4] = new Long JavaDoc(System.currentTimeMillis());
2783                loadedCoplet[5] = new Long JavaDoc(DOMUtil.getValueOf(copletConf, "configuration/timeout", "-1", this.xpathProcessor));
2784                loadedCoplet[7] = statusProfile;
2785
2786                CopletThread copletThread = new CopletThread();
2787                Thread JavaDoc theThread = new Thread JavaDoc(new CocoonRunnable(copletThread));
2788                loadedCoplet[6] = copletThread;
2789                copletThread.init(copletID,
2790                                  ContextHelper.getObjectModel(this.componentContext),
2791                                  this.getLogger(),
2792                                  loadedCoplet,
2793                                  this.manager,
2794                                  this.resolver,
2795                                  this.xpathProcessor);
2796                theThread.start();
2797                Thread.yield();
2798
2799                if (!parallelCoplets) {
2800                    copletThread = (CopletThread)loadedCoplet[6];
2801                    if (copletThread != null) {
2802                        long startTime = System.currentTimeMillis() - ((Long JavaDoc)loadedCoplet[4]).longValue();
2803                        long timeout = ((Long JavaDoc)loadedCoplet[5]).longValue();
2804                        long waitTime;
2805                        if (timeout == -1) {
2806                            waitTime = defaultCopletTimeout;
2807                        } else {
2808                            waitTime = timeout - startTime;
2809                        }
2810
2811                        while (copletThread != null && waitTime > 2) {
2812                            try {
2813                                Thread.sleep(15);
2814                                waitTime -= 15;
2815                            } catch(InterruptedException JavaDoc local) {
2816                                // ignore
2817
}
2818                            copletThread = (CopletThread)loadedCoplet[6];
2819                        }
2820                        loadedCoplet[6] = null; // mark as loaded
2821
}
2822                }
2823
2824            }
2825
2826        }
2827    }
2828
2829    /**
2830     * Process a coplet which is previously loaded
2831     */

2832    private void processCoplet(Object JavaDoc[] loadedCoplet,
2833                               XMLConsumer consumer,
2834                               String JavaDoc notAvailableMessage,
2835                               long defaultCopletTimeout)
2836    throws ProcessingException,
2837           SAXException JavaDoc,
2838           javax.xml.transform.TransformerException JavaDoc {
2839        // calling method is synced
2840

2841        Element JavaDoc copletConf = (Element JavaDoc)loadedCoplet[1];
2842        Element JavaDoc element = (Element JavaDoc)loadedCoplet[3];
2843
2844        String JavaDoc copletID = element.getAttributeNS(null, "id");
2845        if (copletConf != null) {
2846            AttributesImpl JavaDoc attr = new AttributesImpl JavaDoc();
2847            attr.addAttribute("", "id", "id", "CDATA", copletID);
2848            attr.addAttribute("", "number", "number", "CDATA", element.getAttributeNS(null, "number"));
2849            attr.addAttribute("", "position", "position", "CDATA", element.getAttributeNS(null, "position"));
2850            consumer.startElement("", "coplet", "coplet", attr);
2851            attr.clear();
2852
2853            // now include all children of the coplet element except status
2854
NodeList JavaDoc children = copletConf.getChildNodes();
2855            if (children != null && children.getLength() > 0) {
2856                int l = children.getLength();
2857                for(int i = 0; i < l; i++) {
2858                    if (!children.item(i).getNodeName().equals("status")
2859                        && children.item(i).getNodeType() == Node.ELEMENT_NODE) {
2860                        IncludeXMLConsumer.includeNode(children.item(i), consumer, consumer);
2861                    }
2862                }
2863            }
2864
2865            // now the status parameter
2866
// SourceParameters p = DOMUtil.createParameters(DOMUtil.getFirstNodeFromPath(element, new String[] {"status"}, false), null);
2867
consumer.startElement("", "status", "status", attr);
2868            children = DOMUtil.selectNodeList(element, "status/*", this.xpathProcessor);
2869            if (children != null && children.getLength() > 0) {
2870                int l = children.getLength();
2871                for(int i = 0; i < l; i++) {
2872                    if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
2873                        IncludeXMLConsumer.includeNode(children.item(i), consumer, consumer);
2874                    }
2875                }
2876            }
2877            consumer.endElement("", "status", "status");
2878
2879            // now the content:
2880
consumer.startElement("", "content", "content", attr);
2881
2882            CopletThread thread = (CopletThread)loadedCoplet[6];
2883            if (thread != null) {
2884                long startTime = System.currentTimeMillis() - ((Long JavaDoc)loadedCoplet[4]).longValue();
2885                long timeout = ((Long JavaDoc)loadedCoplet[5]).longValue();
2886                long waitTime;
2887                if (timeout == -1) {
2888                    waitTime = defaultCopletTimeout;
2889                } else {
2890                    waitTime = timeout - startTime;
2891                }
2892
2893                while (thread != null && waitTime > 2) {
2894                    try {
2895                        Thread.sleep(15);
2896                        waitTime -= 15;
2897                    } catch(InterruptedException JavaDoc local) {
2898                        // ignore
2899
}
2900                    thread = (CopletThread)loadedCoplet[6];
2901                }
2902            }
2903            byte[] content = (byte[])loadedCoplet[0];
2904            if (content != null) {
2905                if (content.length > 0) {
2906                    XMLDeserializer interpreter = null;
2907                    try {
2908                        interpreter = (XMLDeserializer)this.manager.lookup(XMLDeserializer.ROLE);
2909                        interpreter.setConsumer(new IncludeXMLConsumer(consumer, consumer));
2910                        interpreter.deserialize(content);
2911                    } catch (ComponentException e) {
2912                        throw new ProcessingException("Component for XMLDeserializer not found." + e, e);
2913                    } finally {
2914                        if (interpreter != null) this.manager.release(interpreter);
2915                    }
2916                }
2917            } else {
2918                notAvailableMessage = DOMUtil.getValueOf(copletConf,
2919                         "configuration/messages/coplet_not_available", notAvailableMessage, this.xpathProcessor);
2920                consumer.characters(notAvailableMessage.toCharArray(), 0, notAvailableMessage.length());
2921            }
2922            consumer.endElement("", "content", "content");
2923            consumer.endElement("", "coplet", "coplet");
2924
2925        }
2926    }
2927
2928    /* (non-Javadoc)
2929     * @see org.apache.cocoon.webapps.portal.components.PortalManager#getMediaType()
2930     */

2931    public String JavaDoc getMediaType()
2932    throws ProcessingException {
2933        this.setup();
2934        return this.getMediaManager().getMediaType();
2935    }
2936
2937    /**
2938     * Get the coplet with the id
2939     */

2940    private Element JavaDoc getCopletConfiguration(String JavaDoc copletID,
2941                                           Map JavaDoc defaultCoplets,
2942                                           Map JavaDoc mediaCoplets)
2943    throws ProcessingException {
2944        // calling method is synced
2945
String JavaDoc media = this.getMediaManager().getMediaType();
2946        Map JavaDoc coplets = (Map JavaDoc)mediaCoplets.get(media);
2947        Element JavaDoc coplet = null;
2948        if (coplets != null) coplet = (Element JavaDoc)coplets.get(copletID);
2949        if (coplet == null) coplet = (Element JavaDoc)defaultCoplets.get(copletID);
2950        return coplet;
2951    }
2952
2953    /**
2954     * Get the coplet Element
2955     */

2956    private Element JavaDoc getCopletElement(String JavaDoc copletID,
2957                                     String JavaDoc copletNr,
2958                                     Node JavaDoc[] miscNodes)
2959    throws javax.xml.transform.TransformerException JavaDoc {
2960        // calling method is synced
2961
Element JavaDoc node = null;
2962
2963        // first test content, then header and then footer
2964
int colindex = 8;
2965        while (node == null && colindex < 13) {
2966            if (miscNodes[colindex] != null) {
2967                node = (Element JavaDoc)DOMUtil.getSingleNode(miscNodes[colindex],
2968                        "coplets/coplet[@id='"+copletID+"' and @number='"+copletNr+"']", this.xpathProcessor);
2969                colindex++;
2970            } else {
2971                colindex = 13;
2972            }
2973        }
2974        if (node == null && miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE] != null) {
2975            node = (Element JavaDoc)DOMUtil.getSingleNode(miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE],
2976                      "coplet[@id='"+copletID+"' and @number='"+copletNr+"']", this.xpathProcessor);
2977        }
2978        if (node == null && miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE] != null) {
2979            node = (Element JavaDoc)DOMUtil.getSingleNode(miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE],
2980                      "coplet[@id='"+copletID+"' and @number='"+copletNr+"']", this.xpathProcessor);
2981        }
2982        return node;
2983    }
2984
2985    /**
2986     * Modify the coplet.
2987     * This method returns true if the type informations must be recalculated
2988     */

2989    private boolean modifyCoplet(String JavaDoc requestString,
2990                                 SessionContext context,
2991                                 Map JavaDoc theProfile,
2992                                 DocumentFragment JavaDoc profile)
2993    throws ProcessingException, javax.xml.transform.TransformerException JavaDoc {
2994        // synchronized as the caller is synced
2995
if (this.getLogger().isDebugEnabled()) {
2996            this.getLogger().debug("BEGIN modifyCoplet request=" + requestString);
2997        }
2998        boolean result = false;
2999
3000
3001        int pos, pos2;
3002        pos = requestString.indexOf('_');
3003        pos2 = requestString.indexOf('_', pos+1);
3004        if (pos != -1 && pos2 != -1) {
3005            Element JavaDoc coplet = null;
3006
3007            String JavaDoc copletID;
3008            String JavaDoc copletNr;
3009            String JavaDoc argument = null;
3010
3011            copletID = requestString.substring(pos+1,pos2);
3012            copletNr = requestString.substring(pos2+1);
3013            pos = copletNr.indexOf('_');
3014            if (pos != -1) {
3015                argument = copletNr.substring(pos+1);
3016                copletNr = copletNr.substring(0, pos);
3017            }
3018
3019            // create a new coplet: in the given column, header or footer
3020
if (requestString.startsWith(PortalManagerImpl.REQ_CMD_NEW)
3021                && this.isCopletAvailable(context, copletID,
3022                                 (Map JavaDoc)theProfile.get(PortalConstants.PROFILE_DEFAULT_COPLETS),
3023                                 (Map JavaDoc)theProfile.get(PortalConstants.PROFILE_MEDIA_COPLETS))) {
3024                Node JavaDoc[] miscNodes = (Node JavaDoc[])theProfile.get(PortalConstants.PROFILE_MISC_POINTER);
3025                // determine the coplet number
3026
Node JavaDoc lastCoplet = miscNodes[PortalConstants.PROFILE_MISC_LAST_COPLET_NODE];
3027                String JavaDoc lastNumber = null;
3028                if (lastCoplet != null) {
3029                    lastNumber = ((Element JavaDoc)lastCoplet).getAttributeNS(null, "number");
3030                    if (lastNumber != null) {
3031                        int value = new Integer JavaDoc(lastNumber).intValue();
3032                        value++;
3033                        lastNumber = ""+value;
3034                    }
3035                }
3036                if (lastNumber == null) lastNumber = "0";
3037
3038                Node JavaDoc copletsNode;
3039                if (copletNr.equals("header")) {
3040                    copletsNode = miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE];
3041                    if (copletsNode == null) {
3042                        copletsNode = DOMUtil.selectSingleNode(profile, "profile/portal-profile/content/header", this.xpathProcessor);
3043                        miscNodes[PortalConstants.PROFILE_MISC_HEADER_CONTENT_NODE] = copletsNode;
3044                    } else { // remove old coplet
3045
Node JavaDoc oldCoplet = DOMUtil.getFirstNodeFromPath(copletsNode, new String JavaDoc[] {"coplet"}, false);
3046                        if (oldCoplet != null) copletsNode.removeChild(oldCoplet);
3047                    }
3048                } else if (copletNr.equals("footer")) {
3049                    copletsNode = miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE];
3050                    if (copletsNode == null) {
3051                        copletsNode = DOMUtil.selectSingleNode(profile, "profile/portal-profile/content/footer", this.xpathProcessor);
3052                        miscNodes[PortalConstants.PROFILE_MISC_FOOTER_CONTENT_NODE] = copletsNode;
3053                    } else { // remove old coplet
3054
Node JavaDoc oldCoplet = DOMUtil.getFirstNodeFromPath(copletsNode, new String JavaDoc[] {"coplet"}, false);
3055                        if (oldCoplet != null) copletsNode.removeChild(oldCoplet);
3056                    }
3057                } else {
3058                    Node JavaDoc columnNode = miscNodes[7+new Integer JavaDoc(copletNr).intValue()];
3059                    copletsNode = DOMUtil.getFirstNodeFromPath(columnNode, new String JavaDoc[] {"coplets"}, false);
3060                }
3061                Element JavaDoc copletNode;
3062                Document JavaDoc doc = copletsNode.getOwnerDocument();
3063                copletNode = doc.createElementNS(null, "coplet");
3064                copletsNode.appendChild(copletNode);
3065                copletNode.setAttributeNS(null, "id", copletID);
3066                copletNode.setAttributeNS(null, "number", lastNumber);
3067                // set position
3068
NodeList JavaDoc childs = DOMUtil.getNodeListFromPath(copletsNode, new String JavaDoc[] {"coplet"});
3069                int childsCount = (childs == null ? 0 : childs.getLength());
3070                copletNode.setAttributeNS(null, "position", ""+(childsCount));
3071                miscNodes[PortalConstants.PROFILE_MISC_LAST_COPLET_NODE] = copletNode;
3072
3073                // copy status
3074
Element JavaDoc configElement = this.getCopletConfiguration(copletID,
3075                                                      (Map JavaDoc)theProfile.get(PortalConstants.PROFILE_DEFAULT_COPLETS),
3076                                                      (Map JavaDoc)theProfile.get(PortalConstants.PROFILE_MEDIA_COPLETS));
3077                Element JavaDoc configStatus = (Element JavaDoc)DOMUtil.getFirstNodeFromPath(configElement, new String JavaDoc[] {"status"}, false);
3078                copletNode.appendChild(configStatus.cloneNode(true));
3079
3080                // clear type information for each status
3081
Element JavaDoc status = (Element JavaDoc)copletNode.getElementsByTagName("status").item(0);
3082                NodeList JavaDoc parameters = status.getChildNodes();
3083                Node JavaDoc current;
3084                Element JavaDoc statusNode;
3085                if (parameters != null) {
3086                    for(int i = 0; i < parameters.getLength(); i++) {
3087                        current = parameters.item(i);
3088                        if (current.getNodeType() == Node.ELEMENT_NODE) {
3089                            statusNode = (Element JavaDoc)current;
3090                            if (statusNode.hasAttributeNS(null, "formpath"))
3091                                statusNode.removeAttributeNS(null, "formpath");
3092                            if (statusNode.hasAttributeNS(null, "formtype"))
3093                                statusNode.removeAttributeNS(null, "formtype");
3094                            if (statusNode.hasAttributeNS(null, "formdescription"))
3095                                statusNode.removeAttributeNS(null, "formdescription");
3096                        }
3097                    }
3098                }
3099                result = true;
3100
3101           } else {
3102                coplet = this.getCopletElement(copletID,
3103                                    copletNr,
3104                                    (Node JavaDoc[])theProfile.get(PortalConstants.PROFILE_MISC_POINTER));
3105                if (coplet != null) {
3106                    if (requestString.startsWith(PortalManagerImpl.REQ_CMD_CLOSE) ||
3107                        requestString.startsWith(PortalManagerImpl.REQ_CMD_HIDE)) {
3108                         Node JavaDoc node = DOMUtil.selectSingleNode(coplet, "status/visible", this.xpathProcessor);
3109                         DOMUtil.setValueOfNode(node, "false");
3110                    } else if (requestString.startsWith(PortalManagerImpl.REQ_CMD_OPEN) ||
3111                        requestString.startsWith(PortalManagerImpl.REQ_CMD_SHOW)) {
3112                         Node JavaDoc node = DOMUtil.selectSingleNode(coplet, "status/visible", this.xpathProcessor);
3113                         DOMUtil.setValueOfNode(node, "true");
3114                    } else if (requestString.startsWith(PortalManagerImpl.REQ_CMD_MINIMIZE)) {
3115                         Node JavaDoc node = DOMUtil.selectSingleNode(coplet, "status/size", this.xpathProcessor);
3116                         DOMUtil.setValueOfNode(node, "min");
3117                    } else if (requestString.startsWith(PortalManagerImpl.REQ_CMD_MAXIMIZE)) {
3118                         Node JavaDoc node = DOMUtil.selectSingleNode(coplet, "status/size", this.xpathProcessor);
3119                         DOMUtil.setValueOfNode(node, "max");
3120                    } else if (requestString.startsWith(PortalManagerImpl.REQ_CMD_CUSTOMIZE)) {
3121                         Node JavaDoc node = DOMUtil.selectSingleNode(coplet, "status/customize", this.xpathProcessor);
3122                         DOMUtil.setValueOfNode(node, "true");
3123                    } else if (requestString.startsWith(PortalManagerImpl.REQ_CMD_UPDATE)) {
3124                         Node JavaDoc node = DOMUtil.selectSingleNode(coplet, "status/customize", this.xpathProcessor);
3125                         DOMUtil.setValueOfNode(node, "false");
3126                    } else if (requestString.startsWith(PortalManagerImpl.REQ_CMD_DELETE)) {
3127                        // delete the status of the coplet
3128
Node JavaDoc statusNode = DOMUtil.getSingleNode(profile,
3129                             "profile/status-profile/customization/coplet[@id='"+copletID+"' and @number='"+copletNr+"']", this.xpathProcessor);
3130                        if (statusNode != null) {
3131                            statusNode.getParentNode().removeChild(statusNode);
3132                            Element JavaDoc configElement = this.getCopletConfiguration(copletID,
3133                                                      (Map JavaDoc)theProfile.get(PortalConstants.PROFILE_DEFAULT_COPLETS),
3134                                                      (Map JavaDoc)theProfile.get(PortalConstants.PROFILE_MEDIA_COPLETS));
3135                            boolean isPersistent = DOMUtil.getValueAsBooleanOf(configElement, "configuration/persistent", false, this.xpathProcessor);
3136                            if (isPersistent) {
3137                                // mark the status profile to be saved
3138
theProfile.put(PortalConstants.PROFILE_SAVE_STATUS_FLAG, "true");
3139                            }
3140                        }
3141                        String JavaDoc posAttr = coplet.getAttributeNS(null, "position");
3142                        NodeList JavaDoc followUps = DOMUtil.selectNodeList(coplet.getParentNode(), "coplet[@position > '"+posAttr+"']", this.xpathProcessor);
3143                        coplet.getParentNode().removeChild(coplet);
3144                        coplet = null;
3145                        if (followUps != null) {
3146                            int value;
3147                            for(int i = 0; i < followUps.getLength(); i++) {
3148                                value = new Integer JavaDoc(((Element JavaDoc)followUps.item(i)).getAttributeNS(null, "position")).intValue();
3149                                value -= 1;
3150                                ((Element JavaDoc)followUps.item(i)).setAttributeNS(null, "position", "" + value);
3151                           }
3152                        }
3153                    } else if (requestString.startsWith(PortalManagerImpl.REQ_CMD_MOVE)) {
3154                        if (argument != null) {
3155                            Element JavaDoc copletsElement = (Element JavaDoc)DOMUtil.getSingleNode(profile,
3156                                  "profile/portal-profile/content/column[@position='"+argument+"']/coplets", this.xpathProcessor);
3157                            if (copletsElement != null) {
3158                                if (!coplet.getParentNode().equals(copletsElement)) {
3159                                     String JavaDoc posAttr = coplet.getAttributeNS(null, "position");
3160                                     NodeList JavaDoc followUps = DOMUtil.selectNodeList(coplet.getParentNode(), "coplet[@position > '"+posAttr+"']", this.xpathProcessor);
3161                                     coplet.getParentNode().removeChild(coplet);
3162                                     // set position attribute
3163
NodeList JavaDoc childs = DOMUtil.getNodeListFromPath(copletsElement, new String JavaDoc[] {"coplet"});
3164                                     int childsCount = (childs == null ? 0 : childs.getLength());
3165                                     coplet.setAttributeNS(null, "position", "" + (childsCount + 1));
3166                                     copletsElement.appendChild(coplet);
3167                                     if (followUps != null) {
3168                                         int value;
3169                                         for(int i = 0; i < followUps.getLength(); i++) {
3170                                             value = new Integer JavaDoc(((Element JavaDoc)followUps.item(i)).getAttributeNS(null, "position")).intValue();
3171                                             value -= 1;
3172                                             ((Element JavaDoc)followUps.item(i)).setAttributeNS(null, "position", "" + value);
3173                                         }
3174                                     }
3175                                 }
3176                            }
3177                        }
3178                    } else if (requestString.startsWith(PortalManagerImpl.REQ_CMD_MOVEROW)) {
3179                        if (argument != null) {
3180                            Element JavaDoc newCoplet = (Element JavaDoc)DOMUtil.getSingleNode(coplet.getParentNode(),
3181                                                 "coplet[@position='"+argument+"']", this.xpathProcessor);
3182                            if (newCoplet != null) {
3183                                String JavaDoc position = coplet.getAttributeNS(null, "position");
3184                                coplet.removeAttributeNS(null, "position");
3185                                coplet.setAttributeNS(null, "position", argument);
3186                                newCoplet.removeAttributeNS(null, "position");
3187                                newCoplet.setAttributeNS(null, "position", position);
3188                            }
3189                        }
3190                    }
3191                }
3192            }
3193        }
3194
3195        if (this.getLogger().isDebugEnabled()) {
3196            this.getLogger().debug("END modifyCoplet calculate="+result);
3197        }
3198        return result;
3199    }
3200
3201    /**
3202     * Check if the coplet is available for the current logged in user
3203     * If the user is not logged in, this returns false.
3204     * First the default coplets are searched. If none is found then
3205     * the coplets for each media are searched.
3206     */

3207    private boolean isCopletAvailable(SessionContext context,
3208                                    String JavaDoc copletID,
3209                                    Map JavaDoc defaultCoplets,
3210                                    Map JavaDoc mediaCoplets)
3211    {
3212        // no sync required
3213
if (this.getLogger().isDebugEnabled()) {
3214            this.getLogger().debug("BEGIN isCopletAvailable coplet="+copletID);
3215        }
3216        boolean result = false;
3217
3218        if (context != null) {
3219            result = defaultCoplets.containsKey(copletID);
3220            if (!result) {
3221                Iterator JavaDoc iter = mediaCoplets.values().iterator();
3222                while (!result && iter.hasNext()) {
3223                    result = ((Map JavaDoc)iter.next()).containsKey(copletID);
3224                }
3225            }
3226        }
3227
3228        if (this.getLogger().isDebugEnabled()) {
3229            this.getLogger().debug("END isCopletAvailable result=" + result);
3230        }
3231        return result;
3232    }
3233
3234    /* (non-Javadoc)
3235     * @see org.apache.cocoon.webapps.portal.components.PortalManager#checkAuthentication(org.apache.cocoon.environment.Redirector, java.lang.String)
3236     */

3237    public boolean checkAuthentication(Redirector redirector, String JavaDoc copletID)
3238    throws SAXException JavaDoc, IOException JavaDoc, ProcessingException {
3239        // synchronized
3240
if (this.getLogger().isDebugEnabled()) {
3241            this.getLogger().debug("BEGIN checkAuthentication coplet="+copletID);
3242        }
3243        this.setup();
3244        boolean result = false;
3245        SessionContext context = this.getContext(false);
3246        if (context != null
3247            && context.getAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ROLE) != null) {
3248
3249            try {
3250                this.getTransactionManager().startReadingTransaction(context);
3251                Map JavaDoc theProfile = this.retrieveProfile(this.getProfileID(PortalManagerImpl.BUILDTYPE_VALUE_ID,
3252                     (String JavaDoc)context.getAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ROLE),
3253                     (String JavaDoc)context.getAttribute(PortalManagerImpl.ATTRIBUTE_PORTAL_ID), false));
3254
3255                if (theProfile != null) {
3256                    if (copletID == null || copletID.trim().length() == 0) {
3257                        result = true;
3258                    } else {
3259                        result = this.isCopletAvailable(context,
3260                                      copletID,
3261                                      (Map JavaDoc)theProfile.get(PortalConstants.PROFILE_DEFAULT_COPLETS),
3262                                      (Map JavaDoc)theProfile.get(PortalConstants.PROFILE_MEDIA_COPLETS));
3263                    }
3264                }
3265            } finally {
3266                this.getTransactionManager().stopReadingTransaction(context);
3267            } // end synced
3268
}
3269
3270
3271        if (!result) {
3272            Map JavaDoc config = this.getConfiguration();
3273            if (config != null) {
3274                String JavaDoc redirectURI = (String JavaDoc)config.get(PortalConstants.CONF_AUTH_REDIRECT);
3275                if (redirectURI == null) {
3276                    redirectURI = (String JavaDoc)config.get(PortalConstants.CONF_PORTAL_URI);
3277                }
3278                if (redirectURI != null) {
3279                    redirector.globalRedirect( false, redirectURI );
3280                }
3281            }
3282        }
3283
3284        if (this.getLogger().isDebugEnabled()) {
3285            this.getLogger().debug("END checkAuthentication result=" + result);
3286        }
3287        return result;
3288    }
3289
3290    /**
3291     * Get the configuration. This configuration is an authentication application configuration
3292     * for the current application with the name "portal".
3293     * The first time this configuration is build it is stored in the session
3294     * so later requests get the cached result.
3295     */

3296    private Map JavaDoc getConfiguration()
3297    throws ProcessingException {
3298        // synchronized
3299
if (this.getLogger().isDebugEnabled()) {
3300            this.getLogger().debug("BEGIN getConfiguration");
3301        }
3302        Map JavaDoc result = null;
3303        RequestState reqstate = this.getRequestState();
3304        String JavaDoc appName = reqstate.getApplicationName();
3305        String JavaDoc handlerName = reqstate.getHandlerName();
3306        Session session = this.getSessionManager().getSession(false);
3307        if (session != null && appName != null && handlerName != null) {
3308
3309            synchronized (session) {
3310                result = (Map JavaDoc)session.getAttribute(PortalConstants.ATTRIBUTE_CONFIGURATION + handlerName + ':' + appName);
3311                if (result == null) {
3312
3313                    try {
3314                        Configuration config;
3315
3316                        Configuration conf = reqstate.getModuleConfiguration(PortalConstants.AUTHENTICATION_MODULE_NAME);
3317                        if (conf == null) {
3318                            throw new ProcessingException("portal: Configuration for application '" + appName + "' not found.");
3319                        }
3320                        result = new HashMap JavaDoc(10, 2);
3321                        // auth-redirect (optional)
3322
config = conf.getChild("auth-redirect", false);
3323                        if (config != null) {
3324                            result.put(PortalConstants.CONF_AUTH_REDIRECT, config.getValue());
3325                        }
3326
3327                        // portal-uri (required)
3328
config = conf.getChild("portal-uri", false);
3329                        if (config == null) {
3330                            throw new ProcessingException("portal: portal-uri required for application '"+appName+"'");
3331                        }
3332                        result.put(PortalConstants.CONF_PORTAL_URI, config.getValue());
3333
3334                        // profile-cache (optional)
3335
config = conf.getChild("profile-cache", false);
3336                        if (config != null && config.getValueAsBoolean()) {
3337                            result.put(PortalConstants.CONF_PROFILE_CACHE, appName);
3338                        }
3339
3340                        // parallel coplets
3341
config = conf.getChild("process-coplets-parallel", false);
3342                        if (config != null) {
3343                            result.put(PortalConstants.CONF_PARALLEL_COPLETS, new Boolean JavaDoc(config.getValueAsBoolean(false)));
3344                        } else {
3345                            result.put(PortalConstants.CONF_PARALLEL_COPLETS, Boolean.FALSE);
3346                        }
3347
3348                        // timeout
3349
config = conf.getChild("default-coplet-timeout", false);
3350                        if (config != null) {
3351                            result.put(PortalConstants.CONF_COPLET_TIMEOUT, new Long JavaDoc(config.getValueAsLong(600000)));
3352                        } else {
3353                            result.put(PortalConstants.CONF_COPLET_TIMEOUT, new Long JavaDoc(600000));
3354                        }
3355
3356                        // and now the profile
3357
config = conf.getChild("profile", false);
3358                        if (config == null) throw new ProcessingException("portal: profile configuration required for application '" + appName + "'");
3359                        Configuration child;
3360
3361                        // build resource (optional)
3362
child = config.getChild("buildprofile", false);
3363                        if (child != null) {
3364                            result.put(PortalConstants.CONF_BUILD_RESOURCE, child.getAttribute("uri"));
3365                        }
3366
3367                        // base resource, type is optional
3368
child = config.getChild("layout-base", false);
3369                        if (child == null) {
3370                            throw new ProcessingException("portal: layout-base required for application '" + appName + "'");
3371                        }
3372                        result.put(PortalConstants.CONF_LAYOUTBASE_RESOURCE, child.getAttribute("uri"));
3373                        child = config.getChild("coplet-base", false);
3374                        if (child == null) {
3375                            throw new ProcessingException("portal: coplet-base required for application '" + appName + "'");
3376                        }
3377                        result.put(PortalConstants.CONF_COPLETBASE_RESOURCE, child.getAttribute("uri"));
3378                        child = config.getChild("type-base", false);
3379                        if (child != null) {
3380                            result.put(PortalConstants.CONF_TYPEBASE_RESOURCE, child.getAttribute("uri"));
3381                        }
3382
3383                        // coplet base save (is optional)
3384
child = config.getChild("coplet-base-save", false);
3385                        if (child != null) {
3386                            result.put(PortalConstants.CONF_COPLETBASE_SAVE_RESOURCE, child.getAttribute("uri"));
3387                        }
3388
3389                        // global delta (load required)
3390
child = config.getChild("global-delta-load", false);
3391                        if (child == null) {
3392                            throw new ProcessingException("portal: global-delta-load required for application '" + appName + "'");
3393                        }
3394                        result.put(PortalConstants.CONF_GLOBALDELTA_LOADRESOURCE, child.getAttribute("uri"));
3395                        child = config.getChild("global-delta-save", false);
3396                        if (child != null) {
3397                            result.put(PortalConstants.CONF_GLOBALDELTA_SAVERESOURCE, child.getAttribute("uri"));
3398                        }
3399                        child = config.getChild("global-type-delta", false);
3400                        if (child != null) {
3401                            result.put(PortalConstants.CONF_GLOBALDELTA_TYPERESOURCE, child.getAttribute("uri"));
3402                        }
3403
3404                        // role delta (optional)
3405
child = config.getChild("role-delta-load", false);
3406                        if (child != null) {
3407                            result.put(PortalConstants.CONF_ROLEDELTA_LOADRESOURCE, child.getAttribute("uri"));
3408                        }
3409                        child = config.getChild("role-delta-save", false);
3410                        if (child != null) {
3411                            result.put(PortalConstants.CONF_ROLEDELTA_SAVERESOURCE, child.getAttribute("uri"));
3412                        }
3413                        child = config.getChild("role-type-delta", false);
3414                        if (child != null) {
3415                            result.put(PortalConstants.CONF_ROLEDELTA_TYPERESOURCE, child.getAttribute("uri"));
3416                        }
3417
3418                        // User delta
3419
child = config.getChild("user-delta-load", false);
3420                        if (child != null) {
3421                            result.put(PortalConstants.CONF_USERDELTA_LOADRESOURCE, child.getAttribute("uri"));
3422                        }
3423                        child = config.getChild("user-delta-save", false);
3424                        if (child != null) {
3425                            result.put(PortalConstants.CONF_USERDELTA_SAVERESOURCE, child.getAttribute("uri"));
3426                        }
3427                        child = config.getChild("user-type-delta", false);
3428                        if (child != null) {
3429                            result.put(PortalConstants.CONF_USERDELTA_TYPERESOURCE, child.getAttribute("uri"));
3430                        }
3431
3432                        // Personal information
3433
child = config.getChild("user-status-load", false);
3434                        if (child != null) {
3435                            result.put(PortalConstants.CONF_STATUS_LOADRESOURCE, child.getAttribute("uri"));
3436                        }
3437                        child = config.getChild("user-status-save", false);
3438                        if (child != null) {
3439                            result.put(PortalConstants.CONF_STATUS_SAVERESOURCE, child.getAttribute("uri"));
3440                        }
3441
3442                        // Admin Type profil
3443
child = config.getChild("admin-type-base", false);
3444                        if (child != null) {
3445                            result.put(PortalConstants.CONF_ADMIN_TYPE_BASE, child.getAttribute("uri"));
3446                        }
3447
3448                        // store the config in the session
3449
session.setAttribute(PortalConstants.ATTRIBUTE_CONFIGURATION + handlerName + ':' + appName, result);
3450                    } catch (ConfigurationException conf) {
3451                        throw new ProcessingException("ConfigurationException: " + conf, conf);
3452                    }
3453                }
3454            }
3455
3456        }
3457
3458        if (this.getLogger().isDebugEnabled()) {
3459            this.getLogger().debug("END getConfiguration conf="+result);
3460        }
3461        return result;
3462    }
3463
3464    /**
3465     * Build the profile for the required level if not already done
3466     */

3467    private void createProfile(SessionContext context,
3468                              String JavaDoc type,
3469                              String JavaDoc role,
3470                              String JavaDoc id,
3471                              boolean adminProfile)
3472    throws SAXException JavaDoc, IOException JavaDoc, ProcessingException {
3473        // no sync required
3474
if (this.getLogger().isDebugEnabled() ) {
3475            this.getLogger().debug("BEGIN createProfile context="+context+
3476                                   ", type="+type+
3477                                   ", role="+role+
3478                                   ", id="+id);
3479        }
3480
3481        RequestState reqstate = this.getRequestState();
3482        SourceParameters pars = reqstate.getHandler().getContext().getContextInfoAsParameters();
3483        pars.setSingleParameterValue("type", type);
3484        pars.setSingleParameterValue("admin", (adminProfile ? "true" : "false"));
3485
3486        if (!type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID) || role != null) {
3487            pars.setSingleParameterValue("ID", id);
3488            pars.setSingleParameterValue("role", role);
3489        } else {
3490            id = pars.getParameter("ID", null);
3491            role = pars.getParameter("role", null);
3492        }
3493
3494        Map JavaDoc map = this.getConfiguration();
3495        if (map == null) {
3496            throw new ProcessingException("portal Configuration not found.");
3497        }
3498
3499        // is the configuration build by using a own resource?
3500
String JavaDoc resource = (String JavaDoc)map.get(PortalConstants.CONF_BUILD_RESOURCE);
3501        if (resource != null) {
3502            if (this.getLogger().isInfoEnabled()) {
3503                this.getLogger().info("Building portal profile: " + resource);
3504            }
3505            SourceUtil.readDOM(resource,
3506                               null,
3507                               pars,
3508                               this.resolver);
3509        } else {
3510            this.buildProfile(type, role, id, adminProfile);
3511        }
3512
3513        if (this.getLogger().isDebugEnabled()) {
3514            this.getLogger().debug("END createProfile");
3515        }
3516
3517    }
3518
3519    /**
3520     * Get the base profile for the current application.
3521     * The base profile consists of the layout and the coplet profile
3522     * and optional the type profile
3523     */

3524    private DocumentFragment JavaDoc buildBaseProfile(Map JavaDoc config, boolean adminProfile)
3525    throws ProcessingException {
3526        // calling method is synced
3527
if (this.getLogger().isDebugEnabled()) {
3528            this.getLogger().debug("BEGIN buildBaseProfile config="+config+", adminProfile="+adminProfile);
3529        }
3530        DocumentFragment JavaDoc copletsFragment;
3531        DocumentFragment JavaDoc layoutFragment;
3532        DocumentFragment JavaDoc typeFragment;
3533        DocumentFragment JavaDoc profile;
3534        Document JavaDoc profileDoc;
3535        Element JavaDoc profileRoot;
3536        String JavaDoc res;
3537
3538        SourceParameters pars = new SourceParameters();
3539        RequestState reqstate = this.getRequestState();
3540        pars.setSingleParameterValue("application", reqstate.getApplicationName());
3541        pars.setSingleParameterValue("handler", reqstate.getHandlerName());
3542        pars.setSingleParameterValue("profile", "coplet-base");
3543
3544        // First load the base profiles: copletProfile + layoutProfile
3545
res = (String JavaDoc)config.get(PortalConstants.CONF_COPLETBASE_RESOURCE);
3546        if (res == null) {
3547            throw new ProcessingException("No configuration for portal-coplet base profile found.");
3548        }
3549        if (this.getLogger().isDebugEnabled()) {
3550            this.getLogger().debug("Loading coplet base profile");
3551        }
3552        copletsFragment = SourceUtil.readDOM(res,
3553                               null,
3554                               pars,
3555                               this.resolver);
3556
3557        if (this.getLogger().isDebugEnabled()) {
3558            this.getLogger().debug("coplet base profile loaded");
3559        }
3560        res = (String JavaDoc)config.get(PortalConstants.CONF_LAYOUTBASE_RESOURCE);
3561        if (res == null) {
3562            throw new ProcessingException("No configuration for portal-layout base profile found.");
3563        }
3564        if (this.getLogger().isDebugEnabled()) {
3565            this.getLogger().debug("loading layout base profile");
3566        }
3567        pars.setSingleParameterValue("profile", "layout-base");
3568        layoutFragment = SourceUtil.readDOM(res,
3569                               null,
3570                               pars,
3571                               this.resolver);
3572
3573        if (this.getLogger().isDebugEnabled()) {
3574            this.getLogger().debug("layout base profile loaded");
3575        }
3576        // now create the base profile containing the above profiles
3577
profileDoc = DOMUtil.createDocument();
3578        profile = profileDoc.createDocumentFragment();
3579        profileRoot = profileDoc.createElementNS(null, "profile");
3580        profile.appendChild(profileRoot);
3581        profileRoot.appendChild(profileDoc.importNode(DOMUtil.selectSingleNode(layoutFragment,
3582                                                                  "layout-profile", this.xpathProcessor), true));
3583        profileRoot.appendChild(profileDoc.importNode(DOMUtil.selectSingleNode(copletsFragment,
3584                                                                  "coplets-profile", this.xpathProcessor), true));
3585
3586        // if avalailable append the type profile
3587
if (adminProfile) {
3588            res = (String JavaDoc)config.get(PortalConstants.CONF_ADMIN_TYPE_BASE);
3589            pars.setSingleParameterValue("profile", "admin-type-base");
3590        } else {
3591            res = (String JavaDoc)config.get(PortalConstants.CONF_TYPEBASE_RESOURCE);
3592            pars.setSingleParameterValue("profile", "type-base");
3593        }
3594        if (res != null) {
3595            if (this.getLogger().isDebugEnabled()) {
3596                this.getLogger().debug("loading type base profile");
3597            }
3598            typeFragment = SourceUtil.readDOM(res,
3599                                   null,
3600                                   pars,
3601                                   this.resolver);
3602            profileRoot.appendChild(profileDoc.importNode(DOMUtil.selectSingleNode(typeFragment,
3603                              "type-profile", this.xpathProcessor), true));
3604
3605            if (this.getLogger().isDebugEnabled()) {
3606                this.getLogger().debug("type base profile loaded");
3607            }
3608        }
3609
3610        if (this.getLogger().isDebugEnabled()) {
3611            this.getLogger().debug("END buildBaseProfile profile=" + profile);
3612        }
3613        return profile;
3614    }
3615
3616    /**
3617     * Build the global profile.
3618     */

3619    private void buildGlobalProfile(Element JavaDoc profileRoot,
3620                                    Map JavaDoc config,
3621                                    boolean adminProfile)
3622    throws ProcessingException {
3623        // calling method is synced
3624
if (this.getLogger().isDebugEnabled()) {
3625            this.getLogger().debug("BEGIN buildGlobalProfile profileRoot="+profileRoot+", config="+config+", adminProfile="+adminProfile);
3626        }
3627        DocumentFragment JavaDoc globalFragment;
3628        String JavaDoc res = (String JavaDoc)config.get(PortalConstants.CONF_GLOBALDELTA_LOADRESOURCE);
3629        if (res == null) {
3630            throw new ProcessingException("No configuration for portal-role delta profile found.");
3631        }
3632        SourceParameters pars = new SourceParameters();
3633        RequestState reqstate = this.getRequestState();
3634        pars.setSingleParameterValue("application", reqstate.getApplicationName());
3635        pars.setSingleParameterValue("handler", reqstate.getHandlerName());
3636        pars.setSingleParameterValue("profile", "global-delta");
3637
3638        if (this.getLogger().isDebugEnabled()) {
3639            this.getLogger().debug("loading global profile");
3640        }
3641        globalFragment = SourceUtil.readDOM(res,
3642                                   null,
3643                                   pars,
3644                                   this.resolver);
3645        if (this.getLogger().isDebugEnabled()) {
3646            this.getLogger().debug("global profile loaded");
3647        }
3648        this.importProfileDelta(profileRoot, globalFragment, "global-delta", "layout-delta");
3649        this.importProfileDelta(profileRoot, globalFragment, "global-delta", "coplets-delta");
3650        this.addProfilePart(profileRoot, globalFragment, "global-delta", "portal-profile");
3651        this.addProfilePart(profileRoot, globalFragment, "global-delta", "personal-profile");
3652
3653        // types
3654
res = (String JavaDoc)config.get(PortalConstants.CONF_GLOBALDELTA_TYPERESOURCE);
3655        if (!adminProfile && res != null) {
3656            pars.setSingleParameterValue("profile", "global-type-delta");
3657            if (this.getLogger().isDebugEnabled()) {
3658                this.getLogger().debug("loading global type profile");
3659            }
3660            globalFragment = SourceUtil.readDOM(res,
3661                                       null,
3662                                       pars,
3663                                       this.resolver);
3664            if (this.getLogger().isDebugEnabled()) {
3665                this.getLogger().debug("global type profile loaded");
3666            }
3667            this.addProfilePart(profileRoot, globalFragment, "global-delta", "type-profile");
3668        }
3669        if (this.getLogger().isDebugEnabled()) {
3670            this.getLogger().debug("END buildGlobalProfile");
3671        }
3672    }
3673
3674    /**
3675     * Build the role profile
3676     */

3677    private void buildRoleProfile(Element JavaDoc profileRoot,
3678                                            Map JavaDoc config,
3679                                            String JavaDoc role,
3680                                            boolean adminProfile)
3681    throws ProcessingException {
3682        // calling method is synced
3683

3684        DocumentFragment JavaDoc roleFragment;
3685        RequestState reqstate = this.getRequestState();
3686        SourceParameters pars;
3687        pars = new SourceParameters();
3688        pars.setSingleParameterValue("role", role);
3689        pars.setSingleParameterValue("application", reqstate.getApplicationName());
3690        pars.setSingleParameterValue("handler", reqstate.getHandlerName());
3691        pars.setSingleParameterValue("profile", "role-delta");
3692
3693        String JavaDoc res = (String JavaDoc)config.get(PortalConstants.CONF_ROLEDELTA_LOADRESOURCE);
3694        if (res != null) {
3695            if (this.getLogger().isDebugEnabled()) {
3696                this.getLogger().debug("loading role profile");
3697            }
3698            roleFragment = SourceUtil.readDOM(res,
3699                                       null,
3700                                       pars,
3701                                       this.resolver);
3702            if (this.getLogger().isDebugEnabled()) {
3703                this.getLogger().debug("role profile loaded");
3704            }
3705            this.importProfileDelta(profileRoot, roleFragment, "role-delta", "layout-delta");
3706            this.importProfileDelta(profileRoot, roleFragment, "role-delta", "coplets-delta");
3707            this.addProfilePart(profileRoot, roleFragment, "role-delta", "portal-profile");
3708            this.importProfileDelta(profileRoot, roleFragment, "role-delta", "personal-delta");
3709        }
3710
3711        // types
3712
res = (String JavaDoc)config.get(PortalConstants.CONF_ROLEDELTA_TYPERESOURCE);
3713        if (!adminProfile && res != null) {
3714            pars.setSingleParameterValue("profile", "role-type-delta");
3715            if (this.getLogger().isDebugEnabled()) {
3716                this.getLogger().debug("loading role type profile");
3717            }
3718            roleFragment = SourceUtil.readDOM(res,
3719                                   null,
3720                                   pars,
3721                                   this.resolver);
3722            if (this.getLogger().isDebugEnabled()) {
3723                this.getLogger().debug("role type profile loaded");
3724            }
3725            this.addProfilePart(profileRoot, roleFragment, "role-delta", "type-profile");
3726        }
3727    }
3728
3729    /**
3730     * Build the user profile
3731     */

3732    private void buildUserProfile(Element JavaDoc profileRoot,
3733                                Map JavaDoc config,
3734                                String JavaDoc role,
3735                                String JavaDoc id,
3736                                boolean adminProfile)
3737    throws ProcessingException {
3738        // calling method is synced
3739
DocumentFragment JavaDoc userFragment;
3740        RequestState reqstate = this.getRequestState();
3741        SourceParameters pars;
3742        pars = new SourceParameters();
3743        pars.setSingleParameterValue("ID", id);
3744        pars.setSingleParameterValue("role", role);
3745        pars.setSingleParameterValue("application", reqstate.getApplicationName());
3746        pars.setSingleParameterValue("handler", reqstate.getHandlerName());
3747        pars.setSingleParameterValue("profile", "user-delta");
3748
3749        String JavaDoc res = (String JavaDoc)config.get(PortalConstants.CONF_USERDELTA_LOADRESOURCE);
3750        if (res != null) {
3751            if (this.getLogger().isDebugEnabled()) {
3752                this.getLogger().debug("loading user profile");
3753            }
3754            userFragment = SourceUtil.readDOM(res,
3755                                   null,
3756                                   pars,
3757                                   this.resolver);
3758            if (this.getLogger().isDebugEnabled()) {
3759                this.getLogger().debug("user profile loaded");
3760            }
3761            this.importProfileDelta(profileRoot, userFragment, "user-delta", "layout-delta");
3762            this.importProfileDelta(profileRoot, userFragment, "user-delta", "coplets-delta");
3763            this.addProfilePart(profileRoot, userFragment, "user-delta", "portal-profile");
3764            this.importProfileDelta(profileRoot, userFragment, "user-delta", "personal-delta");
3765        }
3766
3767        // types
3768
res = (String JavaDoc)config.get(PortalConstants.CONF_USERDELTA_TYPERESOURCE);
3769        if (!adminProfile && res != null) {
3770            pars.setSingleParameterValue("profile", "user-type-delta");
3771            if (this.getLogger().isDebugEnabled()) {
3772                this.getLogger().debug("loading user type profile");
3773            }
3774            userFragment = SourceUtil.readDOM(res,
3775                                   null,
3776                                   pars,
3777                                   this.resolver);
3778            if (this.getLogger().isDebugEnabled()) {
3779                this.getLogger().debug("user type profile loaded");
3780            }
3781            this.addProfilePart(profileRoot, userFragment, "user-delta", "type-profile");
3782        }
3783    }
3784
3785    /**
3786     * Load the user status profile (if available)
3787     */

3788    private void buildUserStatusProfile(Element JavaDoc profileRoot,
3789                                        Map JavaDoc config,
3790                                        String JavaDoc role,
3791                                        String JavaDoc id)
3792    throws ProcessingException {
3793        // calling method is synced
3794
String JavaDoc res = (String JavaDoc)config.get(PortalConstants.CONF_STATUS_LOADRESOURCE);
3795
3796        // remove the old status profile
3797
Node JavaDoc statusProfile = DOMUtil.getFirstNodeFromPath(profileRoot, new String JavaDoc[] {"status-profile"}, false);
3798        if (statusProfile != null) {
3799            profileRoot.removeChild(statusProfile);
3800        }
3801
3802        if (res != null) {
3803            DocumentFragment JavaDoc userFragment;
3804            SourceParameters pars;
3805            RequestState reqstate = this.getRequestState();
3806            pars = new SourceParameters();
3807            pars.setSingleParameterValue("ID", id);
3808            pars.setSingleParameterValue("role", role);
3809            pars.setSingleParameterValue("application", reqstate.getApplicationName());
3810            pars.setSingleParameterValue("handler", reqstate.getHandlerName());
3811            pars.setSingleParameterValue("profile", "user-status");
3812            if (this.getLogger().isDebugEnabled()) {
3813                this.getLogger().debug("loading user status profile");
3814            }
3815            userFragment = SourceUtil.readDOM(res,
3816                                   null,
3817                                   pars,
3818                                   this.resolver);
3819            if (this.getLogger().isDebugEnabled()) {
3820                this.getLogger().debug("user status profile loaded");
3821            }
3822            this.addProfilePart(profileRoot, userFragment, null, "status-profile");
3823        }
3824        // test if the status-profile node is available
3825
// if not create one
3826
if (DOMUtil.getFirstNodeFromPath(profileRoot, new String JavaDoc[] {"status-profile"}, false) == null) {
3827            statusProfile = profileRoot.getOwnerDocument().createElementNS(null, "status-profile");
3828            profileRoot.appendChild(statusProfile);
3829        }
3830    }
3831
3832    /**
3833     * Save the user status profile (if available)
3834     */

3835    private void saveUserStatusProfile(Map JavaDoc profile,
3836                                       Map JavaDoc config,
3837                                       String JavaDoc role,
3838                                       String JavaDoc id)
3839    throws ProcessingException {
3840        // calling method is synced
3841
String JavaDoc res = (String JavaDoc)config.get(PortalConstants.CONF_STATUS_SAVERESOURCE);
3842        Element JavaDoc statusProfile = (Element JavaDoc)DOMUtil.getFirstNodeFromPath((DocumentFragment JavaDoc)profile.get(PortalConstants.PROFILE_PROFILE),
3843                         new String JavaDoc[] {"profile","status-profile"}, false);
3844        if (res != null && statusProfile != null) {
3845            DocumentFragment JavaDoc userFragment = statusProfile.getOwnerDocument().createDocumentFragment();
3846            Element JavaDoc saveStatus = (Element JavaDoc)statusProfile.cloneNode(true);
3847            userFragment.appendChild(saveStatus);
3848            // now filter all not persistent coplets!
3849
NodeList JavaDoc list = DOMUtil.getNodeListFromPath(saveStatus, new String JavaDoc[] {"customization","coplet"});
3850            String JavaDoc copletID;
3851            Element JavaDoc coplet;
3852            Element JavaDoc copletConfig;
3853            Map JavaDoc copletConfigs = (Map JavaDoc)profile.get(PortalConstants.PROFILE_DEFAULT_COPLETS);
3854            Map JavaDoc mediaCopletConfigs = (Map JavaDoc)profile.get(PortalConstants.PROFILE_MEDIA_COPLETS);
3855            boolean isPersistent;
3856            for(int i = 0; i < list.getLength(); i++) {
3857                coplet = (Element JavaDoc)list.item(i);
3858                copletID = coplet.getAttributeNS(null, "id");
3859                copletConfig = this.getCopletConfiguration(copletID, copletConfigs, mediaCopletConfigs);
3860                isPersistent = DOMUtil.getValueAsBooleanOf(copletConfig, "configuration/persistent", false, this.xpathProcessor);
3861                if (!isPersistent) {
3862                    coplet.getParentNode().removeChild(coplet);
3863                }
3864            }
3865
3866            try {
3867
3868                RequestState reqstate = this.getRequestState();
3869                SourceParameters pars;
3870                pars = new SourceParameters();
3871                pars.setSingleParameterValue("ID", id);
3872                pars.setSingleParameterValue("role", role);
3873                pars.setSingleParameterValue("application", reqstate.getApplicationName());
3874                pars.setSingleParameterValue("handler", reqstate.getHandlerName());
3875                pars.setSingleParameterValue("profile", "user-status");
3876
3877                SourceUtil.writeDOM(res,
3878                                   null,
3879                                   pars,
3880                                   userFragment,
3881                                   this.resolver,
3882                                   "xml");
3883
3884            } finally {
3885                userFragment.removeChild(saveStatus);
3886            }
3887        }
3888    }
3889
3890    /**
3891     * Change the profile according to the request parameter
3892     */

3893    private void changeProfile()
3894    throws ProcessingException, SAXException JavaDoc, IOException JavaDoc {
3895        // synchronized
3896
if (this.getLogger().isDebugEnabled()) {
3897            this.getLogger().debug("BEGIN changeProfile");
3898        }
3899        Request request = ContextHelper.getRequest(this.componentContext);
3900        SessionContext context = this.getContext(false);
3901
3902        if (context != null) {
3903            try {
3904                Map JavaDoc theProfile = null;
3905                String JavaDoc profileID = request.getParameter(PortalManagerImpl.REQ_PARAMETER_PROFILE);
3906                if (profileID != null) {
3907                    theProfile = this.retrieveProfile(profileID);
3908                }
3909
3910                if (theProfile != null) {
3911                    synchronized (context) {
3912                        DocumentFragment JavaDoc profile = (DocumentFragment JavaDoc)theProfile.get(PortalConstants.PROFILE_PROFILE);
3913                        Node JavaDoc[] miscNodes = (Node JavaDoc[])theProfile.get(PortalConstants.PROFILE_MISC_POINTER);
3914                        Element JavaDoc columns = (Element JavaDoc)miscNodes[PortalConstants.PROFILE_MISC_COLUMNS_NODE];
3915                        Enumeration JavaDoc enumeration = request.getParameterNames();
3916                        String JavaDoc current;
3917                        boolean saveProfile = false;
3918
3919                        // first iteration: all changing commands
3920
while (enumeration.hasMoreElements()) {
3921                            current = (String JavaDoc)enumeration.nextElement();
3922                            if (current.startsWith(PortalManagerImpl.REQ_PARAMETER_CONF)) {
3923                                int pos1, pos2;
3924                                pos1 = current.indexOf('.');
3925                                pos2 = current.indexOf('.', pos1+1);
3926                                if (pos1 != -1 && pos2 != -1) {
3927                                    int pathIndex = new Integer JavaDoc(current.substring(pos1+1, pos2)).intValue();
3928                                    int place= new Integer JavaDoc(current.substring(pos2+1)).intValue();
3929                                    List JavaDoc typePaths = (List JavaDoc)theProfile.get(PortalConstants.PROFILE_TYPE_CONF_PATHS);
3930                                    String JavaDoc path = (String JavaDoc)typePaths.get(pathIndex);
3931                                    if (path != null) {
3932                                        NodeList JavaDoc nodes = DOMUtil.selectNodeList(profile, path, this.xpathProcessor);
3933                                        if (nodes != null) {
3934                                            Node JavaDoc node = nodes.item(place);
3935                                            if (node != null) {
3936                                                if (!node.equals(columns)) {
3937                                                        DOMUtil.setValueOfNode(node, request.getParameter(current));
3938                                                }
3939                                            }
3940                                        }
3941
3942                                    }
3943                                }
3944                            }
3945                        }
3946
3947                        // second: all new
3948
boolean calculate = false;
3949                        enumeration = request.getParameterNames();
3950                        while (enumeration.hasMoreElements()) {
3951
3952                            current = (String JavaDoc)enumeration.nextElement();
3953                            if (current.startsWith(PortalManagerImpl.REQ_PARAMETER_CONF)) {
3954                                int pos1, pos2;
3955                                pos1 = current.indexOf('.');
3956                                pos2 = current.indexOf('.', pos1+1);
3957                                if (pos1 != -1 && pos2 != -1) {
3958                                    int pathIndex = new Integer JavaDoc(current.substring(pos1+1, pos2)).intValue();
3959                                    int place= new Integer JavaDoc(current.substring(pos2+1)).intValue();
3960                                    List JavaDoc typePaths = (List JavaDoc)theProfile.get(PortalConstants.PROFILE_TYPE_CONF_PATHS);
3961                                    String JavaDoc path = (String JavaDoc)typePaths.get(pathIndex);
3962                                    if (path != null) {
3963                                        NodeList JavaDoc nodes = DOMUtil.selectNodeList(profile, path, this.xpathProcessor);
3964                                        if (nodes != null) {
3965                                            Node JavaDoc node = nodes.item(place);
3966                                            if (node != null) {
3967                                                if (node.equals(columns)) {
3968                                                    int columnNumber = new Integer JavaDoc(request.getParameter(current)).intValue();
3969                                                    int oldNumber = new Integer JavaDoc(DOMUtil.getValueOfNode(columns)).intValue();
3970                                                    if (columnNumber > 0 && columnNumber != oldNumber && columnNumber <= PortalConstants.MAX_COLUMNS) {
3971                                                        this.changeColumns(profile,
3972                                                               oldNumber,
3973                                                               columnNumber,
3974                                                               miscNodes);
3975                                                        calculate = true;
3976                                                        DOMUtil.setValueOfNode(node, request.getParameter(current));
3977                                                    }
3978                                                }
3979                                            }
3980                                        }
3981
3982                                    }
3983                                }
3984
3985                            } else if (current.equals(PortalManagerImpl.REQ_PARAMETER_CMD)) {
3986                                String JavaDoc[] cmds = request.getParameterValues(current);
3987                                if (cmds != null && cmds.length > 0) {
3988                                    for(int i = 0; i < cmds.length; i++) {
3989                                        if (cmds[i].equals(PortalManagerImpl.REQ_CMD_SAVEPROFILE)) {
3990                                            saveProfile = true;
3991                                        } else {
3992                                            if (this.modifyCoplet(cmds[i], context, theProfile, profile)) {
3993                                                calculate = true;
3994                                            }
3995                                        }
3996                                    }
3997                                }
3998                            }
3999                        }
4000                        // set type infos
4001
if (calculate) {
4002                            this.setTypeInfo(profile,
4003                                 (List JavaDoc)theProfile.get(PortalConstants.PROFILE_TYPE_PATHS),
4004                                 (List JavaDoc)theProfile.get(PortalConstants.PROFILE_TYPE_CONF_PATHS));
4005                        }
4006
4007                        // test if the status profile changed
4008
Object JavaDoc statusChanged = theProfile.get(PortalConstants.PROFILE_SAVE_STATUS_FLAG);
4009                        if (statusChanged != null) {
4010                            theProfile.remove(PortalConstants.PROFILE_SAVE_STATUS_FLAG);
4011                            this.saveUserStatusProfile(theProfile,
4012                                                       this.getConfiguration(),
4013                                                       this.getRole(profileID),
4014                                                       this.getID(profileID));
4015                        }
4016
4017                        // save the profile
4018
if (saveProfile) {
4019                            Map JavaDoc conf = this.getConfiguration();
4020                            String JavaDoc role = this.getRole(profileID);
4021                            String JavaDoc id = this.getID(profileID);
4022                            String JavaDoc type = this.getType(profileID);
4023                            String JavaDoc saveResource;
4024                            String JavaDoc profileType;
4025
4026                            if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_GLOBAL)) {
4027                                saveResource = (String JavaDoc)conf.get(PortalConstants.CONF_GLOBALDELTA_SAVERESOURCE);
4028                                profileType = "global-delta";
4029                            } else if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ROLE)) {
4030                                saveResource = (String JavaDoc)conf.get(PortalConstants.CONF_ROLEDELTA_SAVERESOURCE);
4031                                profileType = "role-delta";
4032                            } else if (type.equals(PortalManagerImpl.BUILDTYPE_VALUE_ID)) {
4033                                saveResource = (String JavaDoc)conf.get(PortalConstants.CONF_USERDELTA_SAVERESOURCE);
4034                                profileType = "user-delta";
4035                            } else {
4036                                throw new ProcessingException("portal: No save resource defined for type '"+type+"'.");
4037                            }
4038
4039                            // patch
4040
// search for all "status/customize" nodes and set them
4041
// to false
4042
NodeList JavaDoc statusNodes = DOMUtil.selectNodeList(profile,
4043                                    "profile/portal-profile/content/descendant::status/customize", this.xpathProcessor);
4044                            if (statusNodes != null) {
4045                                String JavaDoc value;
4046                                for(int l=0; l < statusNodes.getLength(); l++) {
4047                                    value = DOMUtil.getValueOfNode(statusNodes.item(l));
4048                                    if (value.equals("true")) {
4049                                        DOMUtil.setValueOfNode(statusNodes.item(l), "false");
4050                                    }
4051                                }
4052                            }
4053
4054                            // build delta
4055
RequestState reqstate = this.getRequestState();
4056                            DocumentFragment JavaDoc delta;
4057                            delta = this.buildProfileDelta(type, role, id, this.getIsAdminProfile(profileID));
4058                            SourceParameters pars = new SourceParameters();
4059                            pars.setSingleParameterValue("type", profileType);
4060                            if (id != null) pars.setSingleParameterValue("ID", id);
4061                            if (role != null) pars.setSingleParameterValue("role", role);
4062                            pars.setSingleParameterValue("application", reqstate.getApplicationName());
4063                            pars.setSingleParameterValue("handler", reqstate.getHandlerName());
4064                            SourceUtil.writeDOM(saveResource,
4065                                               null,
4066                                               pars,
4067                                               delta,
4068                                               this.resolver,
4069                                               "xml");
4070
4071                            if (delta.getParentNode() != null) delta.getParentNode().removeChild(delta);
4072                            delta = null;
4073
4074                            // cache the profile
4075
// The profile is only cached if it is already in the cache!
4076
// Why? During login the profile is build and cached, so it is in the cache.
4077
// But: If a user logs in, the profile is cached.
4078
// Now the admin logs in, changes the global profile and saves it.
4079
// The cache is invalidated, including the user profile.
4080
// Now the user changes his profile and saves it.
4081
// If it now would be cached, it would be invalid as it would
4082
// not reflect the changes by the admin.
4083
// But if the old profile is still in the cache, nobody
4084
// has changed a profile above.
4085
// Note CZ: The above is correct, but for building the delta
4086
// the "previous" profile is build and cached ! Thus we can
4087
// easily cache the new profile.
4088
// if (this.isProfileCached(profileID, conf)) {
4089
this.cacheProfile(profileID, theProfile, conf); // cache it
4090
// now the hardest part, clean up the cache
4091
this.cleanUpCache(type, role, conf);
4092// }
4093

4094                        }
4095
4096                    } // end synchronized
4097
}
4098            } catch (javax.xml.transform.TransformerException JavaDoc local) {
4099                throw new ProcessingException("TransformerException: " + local, local);
4100            }
4101        }
4102        if (this.getLogger().isDebugEnabled()) {
4103            this.getLogger().debug("END changeProfile");
4104        }
4105    }
4106
4107    /**
4108     * Change the number of the columns
4109     */

4110    private void changeColumns(DocumentFragment JavaDoc profile,
4111                               int oldNumber,
4112                               int columnNumber,
4113                               Node JavaDoc[] miscNodes)
4114    throws javax.xml.transform.TransformerException JavaDoc {
4115        // calling method is (hopefully) synced
4116
if (columnNumber < oldNumber) {
4117            // remove columns and all coplets to the first one
4118
Node JavaDoc columnNode;
4119            Node JavaDoc firstColumn = DOMUtil.getSingleNode(profile,
4120                        "profile/portal-profile/content/column[@position='1']/coplets", this.xpathProcessor);
4121            NodeList JavaDoc firstColumnCoplets = DOMUtil.getNodeListFromPath(firstColumn, new String JavaDoc[] {"coplet"});
4122            int copletsCount = (firstColumnCoplets == null ? 0 : firstColumnCoplets.getLength());
4123            for(int i = columnNumber + 1; i <= oldNumber; i++) {
4124                columnNode = miscNodes[7+i];
4125                if (columnNode != null) {
4126                    NodeList JavaDoc coplets = DOMUtil.getNodeListFromPath(columnNode, new String JavaDoc[] {"coplets","coplet"});
4127                    Node JavaDoc coplet;
4128                    if (coplets != null && coplets.getLength() > 0) {
4129                        for(int m = 0; m < coplets.getLength(); m++) {
4130                            coplet = coplets.item(m);
4131                            coplet.getParentNode().removeChild(coplet);
4132                            copletsCount++;
4133                            ((Element JavaDoc)coplet).setAttributeNS(null, "position", "" + copletsCount);
4134                            firstColumn.appendChild(coplet);
4135                        }
4136                    }
4137                    columnNode.getParentNode().removeChild(columnNode);
4138                    miscNodes[7+i] = null;
4139                }
4140            }
4141        } else if (columnNumber <= PortalConstants.MAX_COLUMNS) {
4142            // add new columns
4143
Node JavaDoc contentNode = DOMUtil.getFirstNodeFromPath(profile,
4144                        new String JavaDoc[] {"profile","portal-profile","content"}, false);
4145            Document JavaDoc doc = contentNode.getOwnerDocument();
4146            Element JavaDoc newColumn;
4147            Element JavaDoc el;
4148            for(int i = oldNumber + 1; i <= columnNumber; i++) {
4149                newColumn = doc.createElementNS(null, "column");
4150                newColumn.setAttributeNS(null, "position", ""+i);
4151                miscNodes[7+i] = newColumn;
4152                contentNode.appendChild(newColumn);
4153                el = doc.createElementNS(null, "width");
4154                el.appendChild(doc.createTextNode("5%"));
4155                newColumn.appendChild(el);
4156                el = doc.createElementNS(null, "coplets");
4157                newColumn.appendChild(el);
4158            }
4159        }
4160    }
4161
4162    /**
4163     * Send SAX events to the next pipeline component.
4164     * The node is parsed and the events are send to
4165     * the next component in the pipeline.
4166     * @param node The tree to be included.
4167     */

4168    protected void sendEvents(XMLConsumer consumer, Node JavaDoc node)
4169    throws SAXException JavaDoc {
4170        IncludeXMLConsumer.includeNode(node, consumer, consumer);
4171    }
4172
4173    /**
4174     * Get all users in a document fragment with the following children:
4175     * <users>
4176     * <user>
4177     * <ID>...</ID>
4178     * <role>...</role> <!-- optional -->
4179     * <data>
4180     * ...
4181     * </data>
4182     * </user>
4183     * ....
4184     * </users>
4185     * The document fragment might contain further nodes at the root!
4186     * If <code>role</code> is <code>null</code> all users are fetched,
4187     * otherwise only the users for this role.
4188     * If also ID is not null only the single user is fetched.
4189     */

4190    private Document JavaDoc getUsers(String JavaDoc role, String JavaDoc ID)
4191    throws IOException JavaDoc, ProcessingException, SAXException JavaDoc {
4192        // calling method is syned
4193
if (this.getLogger().isDebugEnabled()) {
4194            this.getLogger().debug("BEGIN getUsers role="+role+", ID="+ID);
4195        }
4196        RequestState reqstate = this.getRequestState();
4197        Document JavaDoc frag = null;
4198        Configuration conf = reqstate.getModuleConfiguration("single-role-user-management");
4199        if (conf != null) {
4200
4201            // get load-users resource (optional)
4202
Configuration child = conf.getChild("load-users", false);
4203            if (child != null) {
4204                String JavaDoc loadUsersResource = child.getAttribute("uri", null);
4205                SourceParameters loadUsersResourceParameters = SourceParameters.create(child);
4206
4207                if (loadUsersResource != null) {
4208                    SourceParameters parameters = (loadUsersResourceParameters == null) ? new SourceParameters()
4209
4210                                                                             : loadUsersResourceParameters;
4211                    if (reqstate.getApplicationName() != null)
4212                        parameters.setSingleParameterValue("application", reqstate.getApplicationName());
4213                    if (ID != null) {
4214                        parameters.setSingleParameterValue("type", "user");
4215                        parameters.setSingleParameterValue("ID", ID);
4216                    } else {
4217                        parameters.setSingleParameterValue("type", "users");
4218                    }
4219                    if (role != null) parameters.setSingleParameterValue("role", role);
4220                    frag = this.loadResource(loadUsersResource, parameters);
4221
4222                }
4223            }
4224        }
4225
4226        if (this.getLogger().isDebugEnabled()) {
4227            this.getLogger().debug("END getUsers fragment="+(frag == null ? "null" : XMLUtils.serializeNode(frag, XMLUtils.createPropertiesForXML(false))));
4228        }
4229        return frag;
4230    }
4231
4232    /**
4233     * Get all roles in a document fragment with the following children:
4234     * <roles>
4235     * <role>...</role>
4236     * ....
4237     * </roles>
4238     * The document fragment might contain further nodes at the root!
4239     */

4240    private Document JavaDoc getRoles()
4241    throws IOException JavaDoc, ProcessingException, SAXException JavaDoc {
4242        // calling method is syned
4243
if (this.getLogger().isDebugEnabled()) {
4244            this.getLogger().debug("BEGIN getRoles");
4245        }
4246        Document JavaDoc frag = null;
4247
4248        RequestState reqstate = this.getRequestState();
4249
4250        Configuration conf = reqstate.getModuleConfiguration("single-role-user-management");
4251        if (conf != null) {
4252
4253            // get load-roles resource (optional)
4254
Configuration child = conf.getChild("load-roles", false);
4255            if (child != null) {
4256                String JavaDoc loadRolesResource = child.getAttribute("uri", null);
4257                SourceParameters loadRolesResourceParameters = SourceParameters.create(child);
4258                if (loadRolesResource != null) {
4259                    SourceParameters parameters = (loadRolesResourceParameters == null) ? new SourceParameters()
4260                                                                           : loadRolesResourceParameters;
4261                    if (reqstate.getApplicationName() != null)
4262                        parameters.setSingleParameterValue("application", reqstate.getApplicationName());
4263                    parameters.setSingleParameterValue("type", "roles");
4264                    frag = this.loadResource(loadRolesResource, parameters);
4265                }
4266            }
4267        }
4268
4269        if (this.getLogger().isDebugEnabled()) {
4270            this.getLogger().debug("END getRoles fragment="+frag);
4271        }
4272        return frag;
4273    }
4274
4275    /**
4276     * Load XML resource
4277     */

4278    private Document JavaDoc loadResource(String JavaDoc resource,
4279                               SourceParameters parameters)
4280    throws IOException JavaDoc, ProcessingException, SAXException JavaDoc {
4281        Source source = null;
4282        try {
4283            source = SourceUtil.getSource(resource,
4284                                          null,
4285                                          parameters,
4286                                          this.resolver);
4287            return SourceUtil.toDOM(source);
4288        } catch (SourceException se) {
4289            throw SourceUtil.handle(se);
4290        } finally {
4291            this.resolver.release(source);
4292        }
4293    }
4294
4295    /**
4296     * Get the SessionManager component
4297     */

4298    protected SessionManager getSessionManager()
4299    throws ProcessingException {
4300        if (this.sessionManager == null) {
4301            try {
4302                this.sessionManager = (SessionManager)this.manager.lookup(SessionManager.ROLE);
4303            } catch (ComponentException ce) {
4304                throw new ProcessingException("Error during lookup of SessionManager component.", ce);
4305            }
4306        }
4307        return this.sessionManager;
4308    }
4309
4310    /**
4311     * Get the ContextManager component
4312     */

4313    protected ContextManager getContextManager()
4314    throws ProcessingException {
4315        if (this.contextManager == null) {
4316            try {
4317                this.contextManager = (ContextManager)this.manager.lookup(ContextManager.ROLE);
4318            } catch (ComponentException ce) {
4319                throw new ProcessingException("Error during lookup of ContextManager component.", ce);
4320            }
4321        }
4322        return this.contextManager;
4323    }
4324
4325    /**
4326     * Get the ContextManager component
4327     */

4328    protected TransactionManager getTransactionManager()
4329    throws ProcessingException {
4330        if (this.transactionManager == null) {
4331            try {
4332                this.transactionManager = (TransactionManager)this.manager.lookup(TransactionManager.ROLE);
4333            } catch (ComponentException ce) {
4334                throw new ProcessingException("Error during lookup of TransactionManager component.", ce);
4335            }
4336        }
4337        return this.transactionManager;
4338    }
4339
4340}
4341
Popular Tags