PageRenderTime 60ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/blocks/cocoon-portal/cocoon-portal-sitemap/src/main/java/org/apache/cocoon/portal/transformation/NewEventLinkTransformer.java

https://github.com/apache/cocoon
Java | 231 lines | 120 code | 24 blank | 87 comment | 28 complexity | 47ee5b376bfa58a44742e32f25b5e2e5 MD5 | raw file
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.apache.cocoon.portal.transformation;
  18. import org.apache.cocoon.portal.event.impl.CopletLinkEvent;
  19. import org.apache.cocoon.portal.om.CopletInstance;
  20. import org.apache.cocoon.xml.AttributesImpl;
  21. import org.apache.cocoon.xml.XMLUtils;
  22. import org.xml.sax.Attributes;
  23. import org.xml.sax.ContentHandler;
  24. import org.xml.sax.SAXException;
  25. /**
  26. * This transformer is used to replace links (URIs) from elements
  27. * like <a href="URI"> or <form action="URI"> with portal
  28. * event uris. Therefore the transformer searches for <eventlink>
  29. * elements replaces the URI form the attribute which is specified within
  30. * an attribute called "attribute" and renames the element as specified
  31. * within an attribute called "element".
  32. *
  33. * Example:<br><br>
  34. *
  35. * <pre>
  36. * &lt;root xmlns:ev="http://apache.org/cocoon/portal/eventlink/1.0"&gt;
  37. * &lt;ev:eventlink href="http://eventlinkexample" element="a" attribute="href"&gt;linktext&lt;/ev:eventlink&gt;
  38. * &lt;/root&gt;<br></pre>
  39. *
  40. * will be replaced with something like:<br><br>
  41. *
  42. * <pre>
  43. * &lt;root&gt;
  44. * &lt;a href="portal?cocoon-portal-event=8"&gt;linktext&lt;/a&gt;
  45. * &lt;/root&gt;<br></pre>
  46. *
  47. * The transformer will create two CopletLinkEvents and insert corresponding links
  48. * to them to the XML instead of "http://eventlinkexample". If such a link is pressed
  49. * the corresponding CopletLinkEvent is sent to the Subscribers to be handled.<br>
  50. * Please see also the documentation of superclass AbstractCopletTransformer for how
  51. * the coplet instance data are acquired.
  52. *
  53. * @version $Id$
  54. */
  55. public class NewEventLinkTransformer extends AbstractCopletTransformer {
  56. /**
  57. * The namespace URI to listen for.
  58. */
  59. public static final String NAMESPACE_URI =
  60. "http://apache.org/cocoon/portal/eventlink/1.0";
  61. /**
  62. * The XML element name to listen for.
  63. */
  64. public static final String EVENT_ELEM = "eventlink";
  65. /**
  66. * An attribute's name of EVENT_ELEMENT.
  67. */
  68. public static final String ATTRIBUTE_ATTR = "attribute";
  69. /**
  70. * An attribute's name of EVENT_ELEMENT.
  71. */
  72. public static final String ELEMENT_ATTR = "element";
  73. /**
  74. * @see java.lang.Object#Object()
  75. */
  76. public NewEventLinkTransformer() {
  77. this.defaultNamespaceURI = NAMESPACE_URI;
  78. this.removeOurNamespacePrefixes = true;
  79. }
  80. /**
  81. * @throws SAXException when the eventlink element does not contain the necessary attributes
  82. * "element" and "attribute", retrieving the LinkURI from the LinkService fails,
  83. * or an unknown element within the namespaces in encountered.
  84. * @see org.apache.cocoon.transformation.AbstractSAXTransformer#startTransformingElement(String, String, String, Attributes)
  85. */
  86. public void startTransformingElement(String uri,
  87. String name,
  88. String raw,
  89. Attributes attributes)
  90. throws SAXException {
  91. if (!EVENT_ELEM.equals(name)) {
  92. throw new SAXException("Unknown element encountered: " + name);
  93. }
  94. String attributeName = attributes.getValue(ATTRIBUTE_ATTR);
  95. String elementName = attributes.getValue(ELEMENT_ATTR);
  96. if (attributeName == null) {
  97. throw new SAXException(
  98. "Element "
  99. + EVENT_ELEM
  100. + " must have an attribute "
  101. + ATTRIBUTE_ATTR
  102. + ".");
  103. }
  104. if (elementName == null) {
  105. throw new SAXException(
  106. "Element "
  107. + EVENT_ELEM
  108. + " must have an attribute "
  109. + ELEMENT_ATTR
  110. + ".");
  111. }
  112. // remove ATTRIBUTE_ATTR, ELEMENT_ATTR and "coplet" from attributes
  113. AttributesImpl newAttributes = this.getMutableAttributes(attributes);
  114. newAttributes.removeAttribute(ELEMENT_ATTR);
  115. newAttributes.removeAttribute(ATTRIBUTE_ATTR);
  116. newAttributes.removeAttribute("coplet");
  117. int index = newAttributes.getIndex(attributeName);
  118. String link = newAttributes.getValue(index);
  119. boolean formSpecialTreatment = false;
  120. if ("form".equals(elementName)) {
  121. //cut all query parameters from actions with method get, as these will be normaly ignored!
  122. formSpecialTreatment = true;
  123. if ("GET".equalsIgnoreCase(newAttributes.getValue("method"))
  124. && link.indexOf('?') > 0) {
  125. link = link.substring(0, link.indexOf('?'));
  126. }
  127. }
  128. String portalAction = null;
  129. String portalEvent = null;
  130. // if attribute found that contains a link
  131. if (link != null) {
  132. CopletInstance cid = this.getCopletInstanceData(attributes.getValue("coplet"));
  133. // create event link
  134. CopletLinkEvent event = new CopletLinkEvent(cid, link);
  135. String eventLink = this.portalService.getLinkService().getLinkURI(event);
  136. //form elements need hidden inputs to change request parameters
  137. if (formSpecialTreatment) {
  138. int pos = eventLink.indexOf("cocoon-portal-action=");
  139. if ( pos != -1 ) {
  140. int begin = pos + "cocoon-portal-action=".length();
  141. int end = eventLink.indexOf('&', begin);
  142. if (end == -1) {
  143. end = eventLink.length();
  144. }
  145. portalAction = eventLink.substring(begin, end);
  146. }
  147. pos = eventLink.indexOf("cocoon-portal-event=");
  148. if ( pos != -1 ) {
  149. int begin = pos + "cocoon-portal-event=".length();
  150. int end = eventLink.indexOf('&', begin);
  151. if (end == -1) {
  152. end = eventLink.length();
  153. }
  154. portalEvent = eventLink.substring(begin, end);
  155. }
  156. pos = eventLink.indexOf('?');
  157. if ( pos != -1 ) {
  158. eventLink = eventLink.substring(0, eventLink.indexOf('?'));
  159. }
  160. }
  161. // insert event link
  162. newAttributes.setValue(index, eventLink);
  163. }
  164. this.stack.push(elementName);
  165. XMLUtils.createElement(contentHandler, elementName, newAttributes);
  166. // generate hidden inputs to add request parameters to the form action
  167. if (formSpecialTreatment) {
  168. sendHiddenFields(contentHandler, portalAction, portalEvent);
  169. }
  170. }
  171. /**
  172. * With forms the uri in the action attribute cannot be enhanced with request parameters.
  173. * Instead hidden input fields must be inserted into the SAX stream to add request parameters.
  174. * This method sends two hidden inputs adding the "cocoon-portal-action" parameter and
  175. * the "cocoon-portal-event" parameter.
  176. * @param handler the content handler recieving the SAX events
  177. * @param portalAction value of the "cocoon-portal-action" parameter
  178. * @param portalEvent value of the "cocoon-portal-event" parameter
  179. * @throws SAXException if sending the SAX events failed
  180. */
  181. private void sendHiddenFields(ContentHandler handler,
  182. String portalAction,
  183. String portalEvent)
  184. throws SAXException {
  185. if ( portalAction != null && portalAction.trim().length() > 0 ) {
  186. final AttributesImpl attributes = new AttributesImpl();
  187. attributes.addCDATAAttribute("type", "hidden");
  188. attributes.addCDATAAttribute("name", "cocoon-portal-action");
  189. attributes.addCDATAAttribute("value", portalAction);
  190. XMLUtils.createElement(handler, "input", attributes);
  191. }
  192. if ( portalEvent != null && portalEvent.trim().length() > 0 ) {
  193. final AttributesImpl attributes = new AttributesImpl();
  194. attributes.addCDATAAttribute("type", "hidden");
  195. attributes.addCDATAAttribute("name", "cocoon-portal-event");
  196. attributes.addCDATAAttribute("value", portalEvent);
  197. XMLUtils.createElement(handler, "input", attributes);
  198. }
  199. }
  200. /**
  201. * @see org.apache.cocoon.transformation.AbstractSAXTransformer#endTransformingElement(String, String, String)
  202. */
  203. public void endTransformingElement(String uri, String name, String raw)
  204. throws SAXException {
  205. XMLUtils.createElement(contentHandler, (String) this.stack.pop());
  206. }
  207. }