001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.webapps.authentication.context;
018:
019: import org.apache.avalon.framework.CascadingRuntimeException;
020: import org.apache.avalon.framework.context.Context;
021: import org.apache.avalon.framework.parameters.Parameters;
022:
023: import org.apache.cocoon.ProcessingException;
024: import org.apache.cocoon.components.ContextHelper;
025: import org.apache.cocoon.components.source.SourceUtil;
026: import org.apache.cocoon.environment.Request;
027: import org.apache.cocoon.webapps.authentication.AuthenticationConstants;
028: import org.apache.cocoon.webapps.authentication.components.DefaultAuthenticationManager;
029: import org.apache.cocoon.webapps.authentication.configuration.ApplicationConfiguration;
030: import org.apache.cocoon.webapps.authentication.user.RequestState;
031: import org.apache.cocoon.webapps.authentication.user.UserHandler;
032: import org.apache.cocoon.webapps.session.context.SessionContext;
033: import org.apache.cocoon.webapps.session.context.SimpleSessionContext;
034: import org.apache.cocoon.webapps.session.xml.XMLUtil;
035: import org.apache.cocoon.xml.XMLUtils;
036: import org.apache.cocoon.xml.dom.DOMUtil;
037:
038: import org.apache.excalibur.source.Source;
039: import org.apache.excalibur.source.SourceException;
040: import org.apache.excalibur.source.SourceParameters;
041: import org.apache.excalibur.source.SourceResolver;
042: import org.apache.excalibur.xml.xpath.XPathProcessor;
043: import org.w3c.dom.Document;
044: import org.w3c.dom.DocumentFragment;
045: import org.w3c.dom.Node;
046: import org.w3c.dom.NodeList;
047: import org.xml.sax.ContentHandler;
048: import org.xml.sax.SAXException;
049: import org.xml.sax.ext.LexicalHandler;
050:
051: import java.io.IOException;
052: import java.util.ArrayList;
053: import java.util.HashMap;
054: import java.util.List;
055: import java.util.Map;
056: import java.util.StringTokenizer;
057:
058: /**
059: * This is the implementation for the authentication context
060: *
061: * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
062: * @deprecated This block is deprecated and will be removed in future versions.
063: * @version $Id: AuthenticationContext.java 485224 2006-12-10 17:24:05Z cziegeler $
064: */
065: public class AuthenticationContext implements SessionContext {
066:
067: protected String name;
068: protected UserHandler handler;
069: protected SessionContext authContext;
070: protected String handlerName;
071: protected boolean initialized;
072: protected Context context;
073: protected XPathProcessor xpathProcessor;
074: protected SourceResolver resolver;
075: /** A list of roles the user is in */
076: protected List roles;
077:
078: /**
079: * Read a DOM Fragment from a source
080: *
081: * @param location URI of the Source
082: * @param typeParameters Type of Source query. Currently, only
083: * <code>method</code> parameter (value typically <code>GET</code> or
084: * <code>POST</code>) is recognized. May be <code>null</code>.
085: * @param parameters Parameters (e.g. URL params) of the source.
086: * May be <code>null</code>
087: * @param resolver Resolver for the source.
088: *
089: * @return DOM <code>DocumentFragment</code> constructed from the specified
090: * source.
091: * @throws ProcessingException
092: */
093: public static DocumentFragment readDOM(String location,
094: Parameters typeParameters, SourceParameters parameters,
095: SourceResolver resolver) throws ProcessingException {
096:
097: Source source = null;
098: try {
099: source = SourceUtil.getSource(location, typeParameters,
100: parameters, resolver);
101: Document doc = SourceUtil.toDOM(source);
102:
103: DocumentFragment fragment = doc.createDocumentFragment();
104: fragment.appendChild(doc.getDocumentElement());
105:
106: return fragment;
107: } catch (SourceException e) {
108: throw SourceUtil.handle(e);
109: } catch (IOException e) {
110: throw new ProcessingException(e);
111: } catch (SAXException e) {
112: throw new ProcessingException(e);
113: } finally {
114: resolver.release(source);
115: }
116: }
117:
118: /** Constructor */
119: public AuthenticationContext(Context context,
120: XPathProcessor processor, SourceResolver resolver) {
121: this .context = context;
122: this .xpathProcessor = processor;
123: this .resolver = resolver;
124: }
125:
126: /**
127: * Initialize the context. This method has to be called right after
128: * the constructor.
129: */
130: public void init(UserHandler handler) {
131: this .name = AuthenticationConstants.SESSION_CONTEXT_NAME;
132:
133: this .handler = handler;
134: this .handlerName = this .handler.getHandlerName();
135: try {
136: this .authContext = new SimpleSessionContext(
137: this .xpathProcessor, this .resolver);
138: } catch (ProcessingException pe) {
139: throw new CascadingRuntimeException(
140: "Unable to create simple context.", pe);
141: }
142: }
143:
144: /**
145: * Return the current authentication state
146: */
147: protected RequestState getState() {
148: return DefaultAuthenticationManager
149: .getRequestState(this .context);
150: }
151:
152: /**
153: * Initialize this context
154: */
155: public void init(Document doc) throws ProcessingException {
156: if (initialized) {
157: throw new ProcessingException(
158: "The context can only be initialized once.");
159: }
160: this .authContext.setNode("/", doc.getFirstChild());
161: }
162:
163: /* (non-Javadoc)
164: * @see org.apache.cocoon.webapps.session.context.SessionContext#setup(java.lang.String, java.lang.String, java.lang.String)
165: */
166: public void setup(String value, String load, String save) {
167: // this is not used, everything is set in the constructor
168: }
169:
170: /* (non-Javadoc)
171: * @see org.apache.cocoon.webapps.session.context.SessionContext#getName()
172: */
173: public String getName() {
174: return this .name;
175: }
176:
177: /* (non-Javadoc)
178: * @see org.apache.cocoon.webapps.session.context.SessionContext#getXML(java.lang.String)
179: */
180: public DocumentFragment getXML(String path)
181: throws ProcessingException {
182: if (path == null) {
183: throw new ProcessingException("getXML: Path is required");
184: }
185: if (!path.startsWith("/"))
186: path = '/' + path;
187:
188: final String applicationName = this .getState()
189: .getApplicationName();
190:
191: DocumentFragment frag = null;
192:
193: if (path.equals("/")) {
194: // get all: first authentication then application
195: frag = this .authContext.getXML("/authentication");
196:
197: if (frag != null) {
198: // now add root node authentication
199: Node root = frag.getOwnerDocument().createElementNS(
200: null, "authentication");
201: Node child;
202: while (frag.hasChildNodes()) {
203: child = frag.getFirstChild();
204: frag.removeChild(child);
205: root.appendChild(child);
206: }
207: frag.appendChild(root);
208: }
209:
210: if (applicationName != null) {
211: // join
212: DocumentFragment appFrag = this .authContext
213: .getXML("/applications/" + applicationName);
214: if (appFrag != null) {
215: // now add root node application
216: Node root = appFrag.getOwnerDocument()
217: .createElementNS(null, "application");
218: Node child;
219: while (appFrag.hasChildNodes()) {
220: child = appFrag.getFirstChild();
221: appFrag.removeChild(child);
222: root.appendChild(child);
223: }
224: appFrag.appendChild(root);
225:
226: if (frag == null) {
227: frag = appFrag;
228: } else {
229: while (appFrag.hasChildNodes()) {
230: child = appFrag.getFirstChild();
231: appFrag.removeChild(child);
232: child = frag.getOwnerDocument().importNode(
233: child, true);
234: frag.appendChild(child);
235: }
236: }
237: }
238: }
239:
240: } else if (path.startsWith("/authentication")) {
241: frag = this .authContext.getXML(path);
242:
243: } else if (path.equals("/application")
244: || path.startsWith("/application/")) {
245: if (applicationName != null) {
246: String appPath;
247: if (path.equals("/application")) {
248: appPath = "/";
249: } else {
250: appPath = path.substring("/application".length());
251: }
252: frag = this .authContext.getXML("/applications/"
253: + applicationName + appPath);
254: }
255: } else {
256: frag = this .authContext.getXML(path);
257: }
258:
259: return frag;
260: }
261:
262: /* (non-Javadoc)
263: * @see org.apache.cocoon.webapps.session.context.SessionContext#setXML(java.lang.String, org.w3c.dom.DocumentFragment)
264: */
265: public void setXML(String path, DocumentFragment fragment)
266: throws ProcessingException {
267: if (path == null) {
268: throw new ProcessingException("setXML: Path is required");
269: }
270: if (!path.startsWith("/"))
271: path = '/' + path;
272:
273: final String applicationName = this .getState()
274: .getApplicationName();
275:
276: if (path.equals("/")) {
277: // set all is not allowed with "/"
278: throw new ProcessingException("Path '/' is not allowed");
279:
280: } else if (path.startsWith("/authentication")) {
281:
282: this .cleanParametersCache();
283: this .authContext.setXML(path, fragment);
284:
285: } else if (path.equals("/application")
286: || path.startsWith("/application/")) {
287:
288: if (applicationName == null) {
289: throw new ProcessingException("Application is required");
290: }
291: String appPath;
292: if (path.equals("/application")) {
293: appPath = "/";
294: } else {
295: appPath = path.substring("/application".length());
296: }
297: this .authContext.setXML("/applications/" + applicationName
298: + appPath, fragment);
299:
300: } else {
301: this .authContext.setXML(path, fragment);
302: }
303: }
304:
305: /* (non-Javadoc)
306: * @see org.apache.cocoon.webapps.session.context.SessionContext#appendXML(java.lang.String, org.w3c.dom.DocumentFragment)
307: */
308: public void appendXML(String path, DocumentFragment fragment)
309: throws ProcessingException {
310: if (path == null) {
311: throw new ProcessingException("appendXML: Path is required");
312: }
313: if (!path.startsWith("/"))
314: path = '/' + path;
315:
316: final String applicationName = this .getState()
317: .getApplicationName();
318:
319: if (path.equals("/")) {
320: // set all is not allowed with "/"
321: throw new ProcessingException("Path '/' is not allowed");
322:
323: } else if (path.startsWith("/authentication")) {
324:
325: this .cleanParametersCache();
326: this .authContext.appendXML(path, fragment);
327:
328: } else if (path.equals("/application")
329: || path.startsWith("/application/")) {
330:
331: if (applicationName == null) {
332: throw new ProcessingException("Application is required");
333: }
334: String appPath;
335: if (path.equals("/application")) {
336: appPath = "/";
337: } else {
338: appPath = path.substring("/application".length());
339: }
340: this .authContext.appendXML("/applications/"
341: + applicationName + appPath, fragment);
342:
343: } else {
344: this .authContext.appendXML(path, fragment);
345: }
346: }
347:
348: /* (non-Javadoc)
349: * @see org.apache.cocoon.webapps.session.context.SessionContext#removeXML(java.lang.String)
350: */
351: public void removeXML(String path) throws ProcessingException {
352: if (path == null) {
353: throw new ProcessingException("removeXML: Path is required");
354: }
355: if (!path.startsWith("/"))
356: path = '/' + path;
357:
358: final String applicationName = this .getState()
359: .getApplicationName();
360:
361: if (path.equals("/")) {
362: this .cleanParametersCache();
363: this .authContext.removeXML("/");
364:
365: } else if (path.startsWith("/authentication")) {
366:
367: this .cleanParametersCache();
368: this .authContext.removeXML(path);
369:
370: } else if (path.equals("/application")
371: || path.startsWith("/application/")) {
372: if (applicationName == null) {
373: throw new ProcessingException(
374: "removeXML: Application is required for path "
375: + path);
376: }
377: String appPath;
378: if (path.equals("/application")) {
379: appPath = "/";
380: } else {
381: appPath = path.substring("/application".length());
382: }
383: this .authContext.removeXML("/applications/"
384: + applicationName + appPath);
385: } else {
386: this .authContext.removeXML(path);
387: }
388: }
389:
390: /* (non-Javadoc)
391: * @see org.apache.cocoon.webapps.session.context.SessionContext#setAttribute(java.lang.String, java.lang.Object)
392: */
393: public void setAttribute(String key, Object value)
394: throws ProcessingException {
395: this .authContext.setAttribute(key, value);
396: }
397:
398: /* (non-Javadoc)
399: * @see org.apache.cocoon.webapps.session.context.SessionContext#getAttribute(java.lang.String)
400: */
401: public Object getAttribute(String key) throws ProcessingException {
402: return this .authContext.getAttribute(key);
403: }
404:
405: /* (non-Javadoc)
406: * @see org.apache.cocoon.webapps.session.context.SessionContext#getAttribute(java.lang.String, java.lang.Object)
407: */
408: public Object getAttribute(String key, Object defaultObject)
409: throws ProcessingException {
410: return this .authContext.getAttribute(key, defaultObject);
411: }
412:
413: /**
414: * NOT IMPLEMENTED - throws an exception
415: */
416: public Node getSingleNode(String path) throws ProcessingException {
417: throw new ProcessingException(
418: "This method is not supported by the authenticaton session context.");
419: }
420:
421: /**
422: * NOT IMPLEMENTED - throws an exception
423: */
424: public NodeList getNodeList(String path) throws ProcessingException {
425: throw new ProcessingException(
426: "This method is not supported by the authenticaton session context.");
427: }
428:
429: /**
430: * NOT IMPLEMENTED - throws an exception
431: */
432: public void setNode(String path, Node node)
433: throws ProcessingException {
434: throw new ProcessingException(
435: "This method is not supported by the authenticaton session context.");
436: }
437:
438: /**
439: * NOT IMPLEMENTED - throws an exception
440: */
441: public String getValueOfNode(String path)
442: throws ProcessingException {
443: throw new ProcessingException(
444: "This method is not supported by the authenticaton session context.");
445: }
446:
447: /**
448: * NOT IMPLEMENTED - throws an exception
449: */
450: public void setValueOfNode(String path, String value)
451: throws ProcessingException {
452: throw new ProcessingException(
453: "This method is not supported by the authenticaton session context.");
454: }
455:
456: /* (non-Javadoc)
457: * @see org.apache.cocoon.webapps.session.context.SessionContext#streamXML(java.lang.String, org.xml.sax.ContentHandler, org.xml.sax.ext.LexicalHandler)
458: */
459: public boolean streamXML(String path,
460: ContentHandler contentHandler, LexicalHandler lexicalHandler)
461: throws SAXException, ProcessingException {
462: if (path == null) {
463: throw new ProcessingException("streamXML: Path is required");
464: }
465: if (!path.startsWith("/"))
466: path = '/' + path;
467:
468: final String applicationName = this .getState()
469: .getApplicationName();
470:
471: if (path.equals("/")) {
472: // get all: first authentication then application
473: contentHandler.startElement("", "authentication",
474: "authentication", XMLUtils.EMPTY_ATTRIBUTES);
475: this .authContext.streamXML("/authentication",
476: contentHandler, lexicalHandler);
477: contentHandler.endElement("", "authentication",
478: "authentication");
479:
480: if (applicationName != null) {
481: contentHandler.startElement("", "application",
482: "application", XMLUtils.EMPTY_ATTRIBUTES);
483: this .authContext.streamXML("/applications/"
484: + applicationName, contentHandler,
485: lexicalHandler);
486: contentHandler.endElement("", "application",
487: "application");
488: }
489: return true;
490:
491: } else if (path.startsWith("/authentication")) {
492: return this .authContext.streamXML(path, contentHandler,
493: lexicalHandler);
494:
495: } else if (path.equals("/application")
496: || path.startsWith("/application/")) {
497: if (applicationName != null) {
498: String appPath;
499: if (path.equals("/application")) {
500: appPath = "/";
501: } else {
502: appPath = path.substring("/application".length());
503: }
504: return this .authContext.streamXML("/applications/"
505: + applicationName + appPath, contentHandler,
506: lexicalHandler);
507: }
508: } else {
509: return this .authContext.streamXML(path, contentHandler,
510: lexicalHandler);
511: }
512: return false;
513: }
514:
515: /* (non-Javadoc)
516: * @see org.apache.cocoon.webapps.session.context.SessionContext#loadXML(java.lang.String, org.apache.excalibur.source.SourceParameters)
517: */
518: public void loadXML(String path, SourceParameters parameters)
519: throws SAXException, ProcessingException, IOException {
520: if (!path.startsWith("/"))
521: path = '/' + path;
522:
523: final String applicationName = this .getState()
524: .getApplicationName();
525: if (path.equals("/")) {
526: // load all: first authentication then application
527: this .loadAuthenticationXML("/authentication", parameters,
528: resolver);
529: if (applicationName != null) {
530: this .loadApplicationXML("/", parameters, resolver);
531: }
532:
533: } else if (path.startsWith("/authentication")) {
534: this .loadAuthenticationXML(path, parameters, resolver);
535:
536: } else if (path.equals("/application")
537: && applicationName != null) {
538: this .loadApplicationXML("/", parameters, resolver);
539: } else if (path.startsWith("/application/")
540: && applicationName != null) {
541: this .loadApplicationXML(path.substring(12), // start path with '/'
542: parameters, resolver);
543: } else {
544: throw new ProcessingException(
545: "loadXML: Path is not valid: " + path);
546: }
547: }
548:
549: /* (non-Javadoc)
550: * @see org.apache.cocoon.webapps.session.context.SessionContext#saveXML(java.lang.String, org.apache.excalibur.source.SourceParameters)
551: */
552: public void saveXML(String path, SourceParameters parameters)
553: throws SAXException, ProcessingException, IOException {
554: if (!path.startsWith("/"))
555: path = '/' + path;
556:
557: final String applicationName = this .getState()
558: .getApplicationName();
559:
560: if (path.equals("/")) {
561: // save all: first authentication then application
562: this .saveAuthenticationXML("/authentication", parameters,
563: resolver);
564: if (applicationName != null) {
565: this .saveApplicationXML("/", parameters, resolver);
566: }
567:
568: } else if (path.startsWith("/authentication")) {
569: this .saveAuthenticationXML(path, parameters, resolver);
570:
571: } else if (path.equals("/application")
572: && applicationName != null) {
573: this .saveApplicationXML("/", parameters, resolver);
574: } else if (path.startsWith("/application/")
575: && applicationName != null) {
576: this .saveApplicationXML(path.substring(12), // start path with '/'
577: parameters, resolver);
578: } else {
579: throw new ProcessingException(
580: "saveXML: Path is not valid: " + path);
581: }
582: }
583:
584: /**
585: * Clean the parameters cache
586: */
587: private void cleanParametersCache() throws ProcessingException {
588: this .authContext.setAttribute("cachedmap", null);
589: this .authContext.setAttribute("cachedpar", null);
590: }
591:
592: /**
593: * Save Authentication
594: */
595: private void saveAuthenticationXML(String path,
596: SourceParameters parameters, SourceResolver resolver)
597: throws ProcessingException {
598: String authSaveResource = this .handler
599: .getHandlerConfiguration().getSaveResource();
600: SourceParameters authSaveResourceParameters = this .handler
601: .getHandlerConfiguration().getSaveResourceParameters();
602:
603: if (authSaveResource == null) {
604: throw new ProcessingException("The context " + this .name
605: + " does not support saving.");
606: }
607:
608: synchronized (this .authContext) {
609: DocumentFragment fragment = this .getXML(path);
610: if (fragment == null) {
611: // create empty fake fragment
612: fragment = DOMUtil.createDocument()
613: .createDocumentFragment();
614: }
615: if (parameters != null) {
616: parameters = (SourceParameters) parameters.clone();
617: parameters.add(authSaveResourceParameters);
618: } else if (authSaveResourceParameters != null) {
619: parameters = (SourceParameters) authSaveResourceParameters
620: .clone();
621: }
622: parameters = this .createParameters(parameters, path, false);
623: XMLUtil.writeDOM(authSaveResource, null, parameters,
624: fragment, resolver, "xml");
625: } // end synchronized
626: }
627:
628: /**
629: * Save Authentication
630: */
631: private void loadAuthenticationXML(String path,
632: SourceParameters parameters, SourceResolver resolver)
633: throws ProcessingException {
634: String authLoadResource = this .handler
635: .getHandlerConfiguration().getLoadResource();
636: SourceParameters authLoadResourceParameters = this .handler
637: .getHandlerConfiguration().getLoadResourceParameters();
638:
639: if (authLoadResource == null) {
640: throw new ProcessingException("The context " + this .name
641: + " does not support loading.");
642: }
643:
644: synchronized (this .authContext) {
645:
646: if (parameters != null) {
647: parameters = (SourceParameters) parameters.clone();
648: parameters.add(authLoadResourceParameters);
649: } else if (authLoadResourceParameters != null) {
650: parameters = (SourceParameters) authLoadResourceParameters
651: .clone();
652: }
653: parameters = this .createParameters(parameters, path, false);
654: DocumentFragment frag;
655:
656: frag = readDOM(authLoadResource, null, parameters, resolver);
657:
658: this .setXML(path, frag);
659:
660: } // end synchronized
661: }
662:
663: /**
664: * Load XML of an application
665: */
666: private void loadApplicationXML(String path,
667: SourceParameters parameters, SourceResolver resolver)
668: throws ProcessingException {
669: final String applicationName = this .getState()
670: .getApplicationName();
671:
672: final ApplicationConfiguration conf = (ApplicationConfiguration) this .handler
673: .getHandlerConfiguration().getApplications().get(
674: applicationName);
675: String loadResource = conf.getLoadResource();
676: SourceParameters loadResourceParameters = conf
677: .getLoadResourceParameters();
678: if (loadResource == null) {
679: throw new ProcessingException("The context " + this .name
680: + " does not support loading.");
681: }
682: // synchronized
683: synchronized (this .authContext) {
684:
685: if (parameters != null) {
686: parameters = (SourceParameters) parameters.clone();
687: parameters.add(loadResourceParameters);
688: } else if (loadResourceParameters != null) {
689: parameters = (SourceParameters) loadResourceParameters
690: .clone();
691: }
692: parameters = this .createParameters(parameters, path, true);
693: DocumentFragment fragment;
694: fragment = readDOM(loadResource, null, parameters, resolver);
695: this .authContext.setXML("/applications/" + applicationName
696: + '/', fragment);
697:
698: } // end synchronized
699:
700: }
701:
702: /**
703: * Save XML of an application
704: */
705: private void saveApplicationXML(String path,
706: SourceParameters parameters, SourceResolver resolver)
707: throws ProcessingException {
708: final String applicationName = this .getState()
709: .getApplicationName();
710: final ApplicationConfiguration conf = (ApplicationConfiguration) this .handler
711: .getHandlerConfiguration().getApplications().get(
712: applicationName);
713: String saveResource = conf.getSaveResource();
714: SourceParameters saveResourceParameters = conf
715: .getSaveResourceParameters();
716:
717: if (saveResource == null) {
718: throw new ProcessingException("The context " + this .name
719: + " does not support saving.");
720: }
721: // synchronized
722: synchronized (this .authContext) {
723:
724: if (parameters != null) {
725: parameters = (SourceParameters) parameters.clone();
726: parameters.add(saveResourceParameters);
727: } else if (saveResourceParameters != null) {
728: parameters = (SourceParameters) saveResourceParameters
729: .clone();
730: }
731: parameters = this .createParameters(parameters, path, true);
732: DocumentFragment fragment = this .getXML("/application"
733: + path);
734: if (fragment == null) {
735: // create empty fake fragment
736: fragment = DOMUtil.createDocument()
737: .createDocumentFragment();
738: }
739:
740: XMLUtil.writeDOM(saveResource, null, parameters, fragment,
741: resolver, "xml");
742:
743: } // end synchronized
744:
745: }
746:
747: /**
748: * Build parameters for loading and saving of application data
749: */
750: private SourceParameters createParameters(
751: SourceParameters parameters, String path,
752: boolean appendAppInfo) throws ProcessingException {
753: if (parameters == null)
754: parameters = new SourceParameters();
755:
756: final String applicationName = this .getState()
757: .getApplicationName();
758:
759: // add all elements from inside the handler data
760: this .addParametersFromAuthenticationXML("/data", parameters);
761:
762: // add all top level elements from authentication
763: this .addParametersFromAuthenticationXML("", parameters);
764:
765: // add application and path
766: parameters.setSingleParameterValue("handler", this .handlerName);
767: if (appendAppInfo) {
768: if (applicationName != null)
769: parameters.setSingleParameterValue("application",
770: applicationName);
771: }
772: if (path != null)
773: parameters.setSingleParameterValue("path", path);
774:
775: return parameters;
776: }
777:
778: /**
779: * Convert the authentication XML of a handler to parameters.
780: * The XML is flat and consists of elements which all have exactly one text node:
781: * <parone>value_one<parone>
782: * <partwo>value_two<partwo>
783: * A parameter can occur more than once with different values.
784: */
785: private void addParametersFromAuthenticationXML(String path,
786: SourceParameters parameters) throws ProcessingException {
787: final DocumentFragment fragment = this .authContext
788: .getXML("/authentication" + path);
789: if (fragment != null) {
790: NodeList childs = fragment.getChildNodes();
791: if (childs != null) {
792: Node current;
793: for (int i = 0; i < childs.getLength(); i++) {
794: current = childs.item(i);
795:
796: // only element nodes
797: if (current.getNodeType() == Node.ELEMENT_NODE) {
798: current.normalize();
799: NodeList valueChilds = current.getChildNodes();
800: String key;
801: StringBuffer valueBuffer;
802: String value;
803:
804: key = current.getNodeName();
805: valueBuffer = new StringBuffer();
806: for (int m = 0; m < valueChilds.getLength(); m++) {
807: current = valueChilds.item(m); // attention: current is reused here!
808: if (current.getNodeType() == Node.TEXT_NODE) { // only text nodes
809: if (valueBuffer.length() > 0)
810: valueBuffer.append(' ');
811: valueBuffer.append(current
812: .getNodeValue());
813: }
814: }
815: value = valueBuffer.toString().trim();
816: if (key != null && value != null
817: && value.length() > 0) {
818: parameters.setParameter(key, value);
819: }
820: }
821: }
822: }
823: }
824: }
825:
826: public Map getContextInfo() throws ProcessingException {
827: Map map = (Map) this .authContext.getAttribute("cachedmap");
828: if (map == null) {
829: map = new HashMap(20);
830: Parameters pars = this .createParameters(null, null, false)
831: .getFirstParameters();
832: String[] names = pars.getNames();
833: if (names != null) {
834: String key;
835: String value;
836: for (int i = 0; i < names.length; i++) {
837: key = names[i];
838: value = pars.getParameter(key, null);
839: if (value != null)
840: map.put(key, value);
841: }
842: }
843: this .authContext.setAttribute("cachedmap", map);
844: }
845: return map;
846: }
847:
848: public SourceParameters getContextInfoAsParameters()
849: throws ProcessingException {
850: SourceParameters pars = (SourceParameters) this .authContext
851: .getAttribute("cachedpar");
852: if (pars == null) {
853: pars = this .createParameters(null, null, false);
854: this .authContext.setAttribute("cachedpar", pars);
855: }
856: return pars;
857: }
858:
859: /**
860: * Load XML of an application
861: */
862: public void loadApplicationXML(ApplicationConfiguration appConf,
863: SourceResolver resolver) throws ProcessingException {
864: String loadResource = appConf.getLoadResource();
865: SourceParameters loadResourceParameters = appConf
866: .getLoadResourceParameters();
867: if (!this .handler.isApplicationLoaded(appConf)
868: && loadResource != null) {
869: synchronized (this .authContext) {
870:
871: SourceParameters parameters;
872: if (loadResourceParameters != null) {
873: parameters = (SourceParameters) loadResourceParameters
874: .clone();
875: } else {
876: parameters = new SourceParameters();
877: }
878: parameters = this .createParameters(parameters, null,
879: true);
880: DocumentFragment fragment;
881: fragment = readDOM(loadResource, null, parameters,
882: resolver);
883: this .authContext.setXML("/applications/"
884: + appConf.getName() + '/', fragment);
885:
886: } // end synchronized
887: }
888: this .handler.setApplicationIsLoaded(appConf);
889: }
890:
891: /**
892: * Test if the user has a role
893: * @since 2.1.6
894: */
895: public boolean isUserInRole(String role) {
896: if (this .roles == null) {
897: this .roles = new ArrayList();
898: try {
899: final String allRoles = (String) this .getContextInfo()
900: .get("roles");
901: final StringTokenizer st = new StringTokenizer(
902: allRoles, ",");
903: while (st.hasMoreElements()) {
904: this .roles.add(st.nextElement());
905: }
906: } catch (ProcessingException pe) {
907: // we ignore this
908: }
909: }
910: if (this .roles.contains(role)) {
911: return true;
912: }
913: final Request req = ContextHelper.getRequest(this.context);
914: return req.isUserInRole(role);
915: }
916: }
|