001: /* Copyright 2002 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.channels.webproxy;
007:
008: import org.apache.commons.logging.Log;
009: import org.apache.commons.logging.LogFactory;
010: import org.jasig.portal.utils.SAX2BufferImpl;
011: import org.jasig.portal.utils.SAX2FilterImpl;
012: import org.xml.sax.Attributes;
013: import org.xml.sax.ContentHandler;
014: import org.xml.sax.SAXException;
015: import org.xml.sax.helpers.AttributesImpl;
016:
017: /**
018: * Rewrites URLs for CWebProxy in an XHTML document.
019: * @author Sarah Arnott, sarnott@mun.ca
020: * @version $Revision: 35856 $
021: */
022: public class CWebProxyXHTMLURLFilter extends CWebProxyURLFilter {
023: private static final Log log = LogFactory
024: .getLog(CWebProxyXHTMLURLFilter.class);
025: private SAX2BufferImpl buffer;
026: private boolean insideForm = false;
027: private boolean markedInputExists = false;
028: private String actionURL = null; // either baseActionUrl or downloadActionUrl
029: private String origActionValue = null;
030: private String newActionValue = null;
031: private String passThrough = "";
032:
033: /**
034: * A constructor which receives a ContentHandler to which
035: * filtered SAX events are passed.
036: * @param handler the ContentHandler to which filtered SAX events are passed
037: */
038: public CWebProxyXHTMLURLFilter(ContentHandler handler) {
039: super (handler);
040: }
041:
042: public void startElement(String uri, String localName,
043: String qName, Attributes atts) throws SAXException {
044: AttributesImpl attsImpl = new AttributesImpl(atts);
045:
046: if (attsImpl.getIndex("href") != -1) {
047: String target = atts.getValue("target");
048: // if target exists, do not go through channel
049: if (target == null)
050: rewriteURL("a", "href", qName, atts, attsImpl);
051: if (target == null)
052: rewriteURL("area", "href", qName, atts, attsImpl);
053: rewriteURL("map", "href", qName, atts, attsImpl);
054: } else if (qName.equals("form")) {
055: String target = atts.getValue("target");
056: if (target == null) {
057: passThrough = (String) runtimeData
058: .get("cw_passThrough");
059: if (passThrough.equals("all")
060: || passThrough.equals("marked")
061: || passThrough.equals("application")) {
062: insideForm = true;
063:
064: // determine original action value
065: String attValue = atts.getValue("action");
066: if (attValue != null) {
067: origActionValue = attValue;
068: } else // action attribute required
069: {
070: attsImpl.addAttribute(uri, localName, "action",
071: "CDATA", "");
072: origActionValue = "";
073: }
074:
075: // set up a buffer for form elements
076: buffer = new SAX2BufferImpl(this .contentHandler);
077: buffer.clearBuffer();
078: buffer.startBuffering();
079: }
080: }
081: } else if (qName.equals("input")) {
082: if (insideForm) {
083: String name = atts.getValue("name");
084: if (name != null) {
085: if (name.equals("cw_download"))
086: actionURL = atts.getValue("value");
087: else if (passThrough.equals("marked")
088: && name.equals("cw_inChannelLink"))
089: markedInputExists = true;
090: }
091: }
092: }
093:
094: if (insideForm)
095: buffer.startElement(uri, localName, qName, attsImpl);
096: else
097: super .startElement(uri, localName, qName, attsImpl);
098: }
099:
100: public void endElement(String uri, String localName, String qName)
101: throws SAXException {
102: if (qName.equals("form") && insideForm) {
103: try {
104: initRewrite();
105: insideForm = false;
106: actionURL = null;
107: buffer.endElement(uri, localName, qName);
108: buffer.stopBuffering();
109: buffer
110: .outputBuffer(new FormFilter(
111: this .contentHandler));
112: buffer.clearBuffer();
113: } catch (Exception e) {
114: if (log.isDebugEnabled())
115: log.debug("CWebProxyXHTMLFilter:: Exception: ", e);
116: }
117: } else if (insideForm)
118: buffer.endElement(uri, localName, qName);
119: else
120: super .endElement(uri, localName, qName);
121: }
122:
123: public void characters(char ch[], int start, int length)
124: throws SAXException {
125: if (insideForm)
126: buffer.characters(ch, start, length);
127: else
128: super .characters(ch, start, length);
129: }
130:
131: /**
132: * Sets newActionValue for FormFilter to modify and adds an input
133: * element to buffer, if required.
134: */
135: private void initRewrite() {
136: if (actionURL == null)
137: actionURL = (String) runtimeData.get("baseActionURL");
138:
139: String query = getQueryString(origActionValue);
140: String base = getBase(origActionValue);
141:
142: String xmlUri = (String) runtimeData.get("cw_xml");
143:
144: if (passThrough.equals("all")) {
145: newActionValue = actionURL + query;
146:
147: if (!(origActionValue.trim().equals("") || xmlUri
148: .equals(base)))
149: addInputToBuffer();
150: } else if (passThrough.equals("marked") && markedInputExists) {
151: newActionValue = actionURL + query;
152:
153: if (!(origActionValue.trim().equals("") || xmlUri
154: .equals(base)))
155: addInputToBuffer();
156: } else if (passThrough.equals("application")) {
157: if (origActionValue.trim().equals("")
158: || xmlUri.equals(base))
159: newActionValue = actionURL + query;
160: else
161: newActionValue = origActionValue;
162: } else
163: newActionValue = origActionValue;
164: }
165:
166: /**
167: * Adds an input element to the form to pass original action
168: * attribute value to CWebProxy.
169: */
170: private void addInputToBuffer() {
171: try {
172: AttributesImpl atts = new AttributesImpl();
173: atts.addAttribute("", "", "type", "CDATA", "hidden");
174: atts.addAttribute("", "", "name", "CDATA", "cw_xml");
175: atts
176: .addAttribute("", "", "value", "CDATA",
177: origActionValue);
178: buffer.startElement("", "", "input", atts);
179: buffer.endElement("", "", "input");
180: } catch (SAXException e) {
181: if (log.isInfoEnabled())
182: log
183: .info(
184: "CWebProxyXHTMLURLFilter::cannot add input element to buffer: ",
185: e);
186: }
187: }
188:
189: /**
190: * A helper class which rewrites the action attribute in a form
191: * element.
192: */
193: private class FormFilter extends SAX2FilterImpl {
194: public FormFilter(ContentHandler ch) {
195: super (ch);
196: }
197:
198: public void startElement(String uri, String localName,
199: String qName, Attributes atts) throws SAXException {
200: AttributesImpl attsImpl = new AttributesImpl(atts);
201:
202: if (qName.equals("form")) {
203: int index = attsImpl.getIndex("action");
204: if (index != -1) // action att should always exist
205: {
206: attsImpl.setAttribute(index,
207: attsImpl.getURI(index), attsImpl
208: .getLocalName(index), "action",
209: attsImpl.getType(index), newActionValue);
210: }
211: }
212: super .startElement(uri, localName, qName, attsImpl);
213: }
214: } //end helper class
215:
216: }
|