View Javadoc

1   /*
2    Wotonomy: OpenStep design patterns for pure Java applications.
3    Copyright (C) 2000 Blacksmith, Inc.
4   
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9   
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14  
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, see http://www.gnu.org
17   */
18  
19  package net.wotonomy.web;
20  
21  import java.util.Iterator;
22  import java.util.Map;
23  
24  import net.wotonomy.foundation.NSArray;
25  import net.wotonomy.foundation.NSDictionary;
26  
27  /***
28  * WOHyperlink renders a dynamically generated hyperlink in the output.
29   * Bindings are:
30   * <ul>
31   * <li>string: a string to be included between the hyperlink tags (optional).</li>
32   * <li>escapeHTML: a property returning a value convertable to a Boolean
33   * indicating whether the any html characters in the output should be
34   * escaped so they are shown as html characters rather than interpreted
35   * as html.</li>
36   * <li>href: The URL that the hyperlink should point to.</li>
37   * <li>pageName: The name of the WOComponent that the hyperlink should point to.</li>
38   * <li>directActionName: The name of the direct action to call when the link is activated.</li>
39   * <li>actionClass: The name of the WODirectAction subclass where the direct action resides.</li>
40   * <li>anchorName: The name of the link, for anchor tags.</li>
41   * <li>action: A pointer to a method on the component that contains this element. If the link is activated,
42   *     the method will be called.
43   * <li>ref: The name of the anchor to go to inside the resulting page.</li>
44   * </ul>
45   *
46   * The href, pageName and directActionName/actionClass and name properties are mutually exclusive and you should
47   * only use at most one of them simultaneously.
48   *
49   * @author ezamudio@nasoft.com
50   * @author $Author: cgruber $
51   * @version $Revision: 905 $
52   */
53  public class WOHyperlink extends WODynamicElement {
54  
55      protected String string;
56      protected String href;
57      protected String pageName;
58      protected String directActionName;
59      protected String actionClass;
60      protected String action;
61      protected boolean escapeHTML;
62      protected String anchorName;
63      protected String ref;
64  
65      protected WOHyperlink() {
66          super();
67      }
68  
69      public WOHyperlink(String aName, NSDictionary aMap, WOElement aRootElement) {
70          super(aName, aMap, aRootElement);
71          escapeHTML = true;
72      }
73  
74      public void setString(String value) {
75          string = value;
76      }
77      public String string() {
78          return string;
79      }
80  
81      public void setHref(String value) {
82          href = value;
83      }
84      public String href() {
85          return href;
86      }
87  
88      public void setAnchorName(String value) {
89          anchorName = value;
90      }
91      public String anchorName() {
92          return anchorName;
93      }
94  
95      public void setPageName(String value) {
96          pageName = value;
97      }
98      public String pageName() {
99          return pageName;
100     }
101 
102     public void setDirectActionName(String value) {
103         directActionName = value;
104     }
105     public String directActionName() {
106         return directActionName;
107     }
108 
109     public void setActionClass(String value) {
110         actionClass = value;
111     }
112     public String actionClass() {
113         return actionClass;
114     }
115 
116     /*** Sets the escapeHTML property. */
117     public void setEscapeHTML(boolean escape) {
118         escapeHTML = escape;
119     }
120 
121     /*** If true, inserts escape codes in to the <B>string</B> string so
122         * that HTML special characters (greater-than, less-than, etc.)
123         * appear correctly.  If false, those characters will get
124         * interpreted by the browser.  Defaults to true.
125         */
126     public boolean escapeHTML() {
127         return escapeHTML;
128     }
129 
130     public String actionURL(WOContext c) {
131         //Check if the href property is set
132         if (href() != null) {
133             return href();
134         } else if (pageName() != null || associations.objectForKey("action") != null) { //write this component's URL
135             StringBuffer retval = new StringBuffer(c.componentActionURL());
136             Map addFields = urlFields(c.component());
137             if (addFields.size() > 0) {
138                 Iterator enumeration = addFields.keySet().iterator();
139                 retval.append('?');
140                 while (enumeration.hasNext()) {
141                 	String encoding = c.response() != null ? c.response().contentEncoding() : c.request().contentEncoding();
142                     String key = (String)enumeration.next();
143                     try {
144 						retval.append(java.net.URLEncoder.encode(key, encoding));
145                     } catch (java.io.UnsupportedEncodingException ex) {
146                     	retval.append(key);
147                     }
148                     retval.append("=");
149 					try {
150 						retval.append(java.net.URLEncoder.encode(addFields.get(key).toString(), encoding));
151 					} catch (java.io.UnsupportedEncodingException e) {
152 						retval.append(addFields.get(key).toString());
153 					}
154                     if (enumeration.hasNext())
155                         retval.append('&');
156                 }
157             }
158             return retval.toString();
159         } else if (directActionName() != null) { //compose the direct action URL
160             String fullActionName = null;
161             if (actionClass() != null )
162                 fullActionName = actionClass() + "/" + directActionName();
163             else
164                 fullActionName = directActionName();
165             return c.directActionURLForActionNamed(fullActionName, urlFields(c.component()));
166         }
167         return null;
168     }
169     
170     protected void pullValuesFromParent(WOComponent c) {
171         string = stringForProperty("string", c);
172         href = stringForProperty("href", c);
173         pageName = stringForProperty("pageName", c);
174         directActionName = stringForProperty("directActionName", c);
175         actionClass = stringForProperty("actionClass", c);
176         //action = stringForProperty("action", c);
177         escapeHTML = booleanForProperty("escapeHTML", c);
178         anchorName = stringForProperty("anchorName", c);
179         ref = stringForProperty("ref", c);
180     }
181 
182     public void appendToResponse(WOResponse r, WOContext c) {
183         pullValuesFromParent( c.component() );
184         r.appendContentString("<A");
185         boolean closeQuotes = false;
186         //Check if the href property is set
187         String _href = actionURL(c);
188         if (_href != null) {
189             closeQuotes = true;
190             r.appendContentString(" HREF=\"");
191             r.appendContentString(_href);
192         } else if (anchorName() != null) {
193             r.appendContentString(" NAME=\"");
194             r.appendContentString(anchorName());
195             closeQuotes = true;
196         }
197         if (ref != null) {
198             if (!closeQuotes) {
199                 r.appendContentString(" HREF=\"#");
200                 closeQuotes = true;
201             } else
202                 r.appendContentString("#");
203             r.appendContentString(ref);
204         }
205         if (closeQuotes)
206             r.appendContentString("\"");
207         r.appendContentString(additionalHTMLProperties(c.component(), new NSArray(new Object[]{
208             "name", "href", "pageName", "action", "directActionName", "actionClass", "anchorName",
209             "escapeHTML", "string" })));
210         r.appendContentString(">");
211         //Append the string if present
212         if (string() != null) {
213             if (escapeHTML())
214                 r.appendContentHTMLString(string());
215             else
216                 r.appendContentString(string());
217         }
218         //If there is a template, call appendToResponse on it
219         if (rootElement != null) {
220             rootElement.appendToResponse(r, c);
221         }
222         //Close the tag
223         r.appendContentString("</A>");
224     }
225 
226     public WOActionResults invokeAction(WORequest r, WOContext c) {
227         System.out.println("invoke action with elementID=" + c.elementID() + " senderID=" + c.senderID());
228         //Check if this element is the target
229         if (c.senderID().equals(c.elementID())) {
230             if (pageName() != null)
231             {
232                 return WOApplication.application().pageWithName(pageName(), r);
233             }
234             else 
235             {
236                 WOAssociation ass = (WOAssociation) associations.objectForKey("action");
237                 if ( ass != null && ass.path != null ) //??
238                 return (WOActionResults)c.component().performAction( ass.path );
239             }
240         }
241         return null;
242     }
243 
244     public void takeValuesFromRequest(WORequest r, WOContext c) {
245         System.out.println("takeValuesFromRequest elementID=" + c.elementID() + " senderID=" + c.senderID());
246         super.takeValuesFromRequest(r, c);
247     }
248 
249 }