Coverage Report - net.fckeditor.FCKeditor
 
Classes in this File Line Coverage Branch Coverage Complexity
FCKeditor
17%
17/99
21%
6/28
2,25
 
 1  
 /*
 2  
  * FCKeditor - The text editor for Internet - http://www.fckeditor.net
 3  
  * Copyright (C) 2004-2009 Frederico Caldeira Knabben
 4  
  * 
 5  
  * == BEGIN LICENSE ==
 6  
  * 
 7  
  * Licensed under the terms of any of the following licenses at your
 8  
  * choice:
 9  
  * 
 10  
  *  - GNU General Public License Version 2 or later (the "GPL")
 11  
  *    http://www.gnu.org/licenses/gpl.html
 12  
  * 
 13  
  *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 14  
  *    http://www.gnu.org/licenses/lgpl.html
 15  
  * 
 16  
  *  - Mozilla Public License Version 1.1 or later (the "MPL")
 17  
  *    http://www.mozilla.org/MPL/MPL-1.1.html
 18  
  * 
 19  
  * == END LICENSE ==
 20  
  */
 21  
 package net.fckeditor;
 22  
 
 23  
 import javax.servlet.http.HttpServletRequest;
 24  
 
 25  
 import net.fckeditor.handlers.PropertiesLoader;
 26  
 import net.fckeditor.tool.Compatibility;
 27  
 import net.fckeditor.tool.Utils;
 28  
 import net.fckeditor.tool.XHtmlTagTool;
 29  
 
 30  
 /**
 31  
  * Java representation of the <a href="http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Server_Side_Integration#FCKeditor_Creator"
 32  
  * target="_blank">FCKeditor</a>. This representation reflects the editor in an
 33  
  * object-oriented way. It can be configured as any other JavaBean type class.
 34  
  * The final output of this class is HTML code.<br />
 35  
  * <strong>Note:</strong> It's your responsibility to supply reasonable and
 36  
  * valid values, only {@code request} and {@code instanceName} will be checked
 37  
  * for sanity.
 38  
  * 
 39  
  * @version $Id: FCKeditor.java 3695 2009-06-18 20:18:38Z mosipov $
 40  
  */
 41  
 public class FCKeditor {
 42  
 
 43  6
         private FCKeditorConfig fckConfig = new FCKeditorConfig();
 44  
         private String instanceName;
 45  
         private String value;
 46  
         private HttpServletRequest request;
 47  
 
 48  
         // defaults
 49  6
         private String toolbarSet = PropertiesLoader.getEditorToolbarSet();
 50  6
         private String width = PropertiesLoader.getEditorWidth();
 51  6
         private String height = PropertiesLoader.getEditorHeight();
 52  6
         private String basePath = PropertiesLoader.getEditorBasePath();
 53  
 
 54  
         /**
 55  
          * Class constructor with all basic parameters.
 56  
          * 
 57  
          * A constructors which handles basic FCKeditor initialization with a few
 58  
          * parameters. If you omit basic parameters, default ones will be taken from
 59  
          * the {@link PropertiesLoader properties file}.
 60  
          * 
 61  
          * @param request
 62  
          *            current user request instance
 63  
          * @param instanceName
 64  
          *            the unique name of this editor
 65  
          * @param width
 66  
          *            the desired editor width (CSS-style value)
 67  
          * @param height
 68  
          *            the desired editor height (CSS-style value)
 69  
          * @param toolbarSet
 70  
          *            the desired toolbar set name
 71  
          * @param value
 72  
          *            the HTML markup of this editor. Markup will be properly
 73  
          *            escaped.
 74  
          * @param basePath
 75  
          *            the base path of this editor, absolute to the context
 76  
          * @throws IllegalArgumentException
 77  
          *             if instanceName is empty or not a valid XHTML id
 78  
          */
 79  
         public FCKeditor(final HttpServletRequest request,
 80  
                         final String instanceName, final String width, final String height,
 81  
                         final String toolbarSet, final String value, final String basePath) {
 82  
 
 83  0
                 this(request, instanceName);
 84  0
                 this.width = width;
 85  0
                 this.height = height;
 86  0
                 this.toolbarSet = toolbarSet;
 87  0
                 this.value = value;
 88  0
                 this.basePath = basePath;
 89  
 
 90  0
         }
 91  
 
 92  
         /**
 93  
          * Class constructor with a minimal set of parameters.
 94  
          * 
 95  
          * Omitted parameters will be set to default values.
 96  
          * 
 97  
          * @param request
 98  
          *            current user request instance
 99  
          * @param instanceName
 100  
          *            the unique name of this editor
 101  
          * @throws IllegalArgumentException
 102  
          *             if instanceName is empty or not a valid HTML id
 103  
          */
 104  6
         public FCKeditor(final HttpServletRequest request, final String instanceName) {
 105  
 
 106  6
                 if (request == null)
 107  1
                         throw new NullPointerException("the request cannot be null");
 108  5
                 this.request = request;
 109  
 
 110  5
                 setInstanceName(instanceName);
 111  
 
 112  1
         }
 113  
 
 114  
         /**
 115  
          * Sets the unique name of this editor.
 116  
          * 
 117  
          * @param instanceName
 118  
          *            the unique name of this editor
 119  
          * @throws IllegalArgumentException
 120  
          *             if instanceName is empty or not a valid XHTML id
 121  
          */
 122  
         public void setInstanceName(final String instanceName) {
 123  5
                 if (Utils.isEmpty(instanceName))
 124  2
                         throw new IllegalArgumentException("instanceName cannot be empty");
 125  3
                 if (!instanceName.matches("\\p{Alpha}[\\p{Alnum}:_.-]*"))
 126  2
                         throw new IllegalArgumentException(
 127  
                                         "instanceName must be a valid XHTML id containing only \"\\p{Alpha}[\\p{Alnum}:_.-]*\"");
 128  1
                 this.instanceName = instanceName;
 129  1
         }
 130  
 
 131  
         /**
 132  
          * Sets the initial value to be edited as HTML markup.
 133  
          * 
 134  
          * @param value
 135  
          *            the HTML markup of this editor. Markup will be properly
 136  
          *            escaped.
 137  
          */
 138  
         public void setValue(final String value) {
 139  0
                 this.value = value;
 140  0
         }
 141  
 
 142  
         /**
 143  
          * Sets the base path of this editor. The base path reflects the location of
 144  
          * the editor files absolute to the context root <i>not</i> the server root.
 145  
          * 
 146  
          * @param basePath
 147  
          *            the base path of this editor, absolute to the context
 148  
          */
 149  
         public void setBasePath(final String basePath) {
 150  0
                 this.basePath = basePath;
 151  0
         }
 152  
 
 153  
         /**
 154  
          * Sets the name of the toolbar set of this editor.
 155  
          * 
 156  
          * @param toolbarSet
 157  
          *            the desired toolbar set name
 158  
          */
 159  
         public void setToolbarSet(final String toolbarSet) {
 160  0
                 this.toolbarSet = toolbarSet;
 161  0
         }
 162  
 
 163  
         /**
 164  
          * Sets the width of this editor. This value can be any valid CSS width
 165  
          * value.
 166  
          * 
 167  
          * @param width
 168  
          *            the desired editor width (CSS-style value)
 169  
          */
 170  
         public void setWidth(final String width) {
 171  0
                 this.width = width;
 172  0
         }
 173  
 
 174  
         /**
 175  
          * Sets the height of this editor. This value can be any valid CSS height
 176  
          * value.
 177  
          * 
 178  
          * @param height
 179  
          *            the desired editor height (CSS-style value)
 180  
          */
 181  
         public void setHeight(final String height) {
 182  0
                 this.height = height;
 183  0
         }
 184  
 
 185  
         /**
 186  
          * Gets the advanced configuration map. Each configuration element has to be
 187  
          * set individually in this map.<br />
 188  
          * The editor provides already a system-wide configuration through the
 189  
          * <code>config.js</code> file. By adding elements to this map you can
 190  
          * override the configuration for each editor instance.
 191  
          * 
 192  
          * @deprecated Method will be removed in FCKeditor.Java 2.6, use
 193  
          *             {@link FCKeditor#getConfig(String)}.
 194  
          * @see #getConfig(String)
 195  
          * @return configuration configuration map for this editor instance
 196  
          */
 197  
         @Deprecated
 198  
         public FCKeditorConfig getConfig() {
 199  0
                 return fckConfig;
 200  
         }
 201  
 
 202  
         /**
 203  
          * Returns a configuration option. See {@link FCKeditorConfig} for more
 204  
          * details.
 205  
          * 
 206  
          * @param name
 207  
          *            the name of the parameter (case-sensitive)
 208  
          * @return the value represented by this parameter, else null
 209  
          */
 210  
         public String getConfig(String name) {
 211  0
                 return fckConfig.get(name);
 212  
         }
 213  
 
 214  
         /**
 215  
          * Sets a configuration option. See {@link FCKeditorConfig} for more
 216  
          * details.
 217  
          * 
 218  
          * @param name
 219  
          *            the name of the config option (case-sensitive)
 220  
          * @param value
 221  
          *            the value of the config option. Null values will be ignored.
 222  
          */
 223  
         public void setConfig(String name, String value) {
 224  0
                 if (value != null)
 225  0
                         fckConfig.put(name, value);
 226  0
         }
 227  
 
 228  
         /**
 229  
          * Sets the advanced configuration maps. <strong>Note:</strong> previously
 230  
          * 
 231  
          * @deprecated Method will be removed in FCKeditor.Java 2.6, use
 232  
          *             {@link #setConfig(String, String)}.
 233  
          * @see #setConfig(String, String)
 234  
          * @param config
 235  
          *            configuration collection
 236  
          */
 237  
         @Deprecated
 238  
         public void setConfig(FCKeditorConfig config) {
 239  0
                 this.fckConfig = config;
 240  0
         }
 241  
 
 242  
         /**
 243  
          * Escapes base XML entities as specified <a
 244  
          * href="http://en.wikipedia.org/wiki/Xml#Entity_references">here</a>.
 245  
          * 
 246  
          * @param str
 247  
          *            string to escape, empty strings will be ignored
 248  
          * @return escaped string
 249  
          */
 250  
         private String escapeXml(String str) {
 251  
 
 252  0
                 if (Utils.isEmpty(str))
 253  0
                         return str;
 254  
 
 255  0
                 StringBuffer sb = new StringBuffer();
 256  
 
 257  0
                 int len = str.length();
 258  
                 char c;
 259  
 
 260  0
                 for (int i = 0; i < len; i++) {
 261  
 
 262  0
                         c = str.charAt(i);
 263  0
                         switch (c) {
 264  
                         case '&':
 265  0
                                 sb.append("&amp;");
 266  0
                                 break;
 267  
                         case '<':
 268  0
                                 sb.append("&lt;");
 269  0
                                 break;
 270  
                         case '>':
 271  0
                                 sb.append("&gt;");
 272  0
                                 break;
 273  
                         case '"':
 274  0
                                 sb.append("&quot;");
 275  0
                                 break;
 276  
                         // XML actually defines &apos; as entity for the apostrophe but we
 277  
                         // user rather the numerical reference to avoid XHTML 1.0 validation
 278  
                         // problems
 279  
                         case '\'':
 280  0
                                 sb.append("&#39;");
 281  0
                                 break;
 282  
                         default:
 283  0
                                 sb.append(c);
 284  
                                 break;
 285  
                         }
 286  
                 }
 287  
 
 288  0
                 return sb.toString();
 289  
         }
 290  
 
 291  
         /**
 292  
          * Creates the HTML representation of this editor instance. First of all,
 293  
          * this method determines whether the request browser is supported.
 294  
          * According to the result an appropriate HTML representation is assembled
 295  
          * and returned.
 296  
          * 
 297  
          * @return HTML representation of this editor instance
 298  
          */
 299  
         @Override
 300  
         public String toString() {
 301  0
                 StringBuffer strEditor = new StringBuffer();
 302  
 
 303  0
                 strEditor.append("<div>");
 304  0
                 String encodedValue = escapeXml(value);
 305  
 
 306  0
                 if (Compatibility.isCompatibleBrowser(request)) {
 307  0
                         strEditor.append(createInputForVariable(instanceName, instanceName,
 308  
                                         encodedValue));
 309  
 
 310  
                         // create config HTML
 311  0
                         String configStr = fckConfig.getUrlParams();
 312  0
                         if (Utils.isNotEmpty(configStr))
 313  0
                                 strEditor.append(createInputForVariable(null, instanceName
 314  
                                                 .concat("___Config"), configStr));
 315  
 
 316  
                         // create IFrame
 317  0
                         StringBuffer editorLink = new StringBuffer(request.getContextPath());
 318  0
                         editorLink.append(basePath);
 319  0
                         editorLink.append("/editor/fckeditor.html?InstanceName=").append(
 320  
                                         instanceName);
 321  0
                         if (Utils.isNotEmpty(toolbarSet))
 322  0
                                 editorLink.append("&amp;Toolbar=").append(toolbarSet);
 323  
 
 324  0
                         XHtmlTagTool iframeTag = new XHtmlTagTool("iframe",
 325  
                                         XHtmlTagTool.SPACE);
 326  0
                         iframeTag.addAttribute("id", instanceName.concat("___Frame"));
 327  0
                         iframeTag.addAttribute("src", editorLink.toString());
 328  0
                         iframeTag.addAttribute("width", width);
 329  0
                         iframeTag.addAttribute("height", height);
 330  0
                         iframeTag.addAttribute("frameborder", "0");
 331  0
                         iframeTag.addAttribute("scrolling", "no");
 332  0
                         strEditor.append(iframeTag);
 333  
 
 334  0
                 } else {
 335  0
                         XHtmlTagTool textareaTag = new XHtmlTagTool("textarea",
 336  
                                         encodedValue);
 337  0
                         textareaTag.addAttribute("name", instanceName);
 338  0
                         textareaTag.addAttribute("rows", "4");
 339  0
                         textareaTag.addAttribute("cols", "40");
 340  0
                         textareaTag.addAttribute("wrap", "virtual");
 341  0
                         textareaTag.addAttribute("style", "width: ".concat(width).concat(
 342  
                                         "; height: ").concat(height));
 343  
                 }
 344  0
                 strEditor.append("</div>");
 345  0
                 return strEditor.toString();
 346  
         }
 347  
 
 348  
         /**
 349  
          * Creates the HTML representation of this editor instance.
 350  
          * 
 351  
          * @see #toString()
 352  
          * @return HTML representation of this editor instance
 353  
          */
 354  
         public String createHtml() {
 355  0
                 return toString();
 356  
         }
 357  
 
 358  
         /**
 359  
          * Creates a hidden input element for the given attributes.
 360  
          * 
 361  
          * @param name
 362  
          *            name attribute of the input tag
 363  
          * @param id
 364  
          *            id attribute of the input tag
 365  
          * @param value
 366  
          *            value attribute of the input tag
 367  
          * @return the produced XHTML tag
 368  
          */
 369  
         private String createInputForVariable(final String name, final String id,
 370  
                         final String value) {
 371  0
                 XHtmlTagTool tag = new XHtmlTagTool("input");
 372  0
                 if (Utils.isNotEmpty(id))
 373  0
                         tag.addAttribute("id", id);
 374  0
                 if (Utils.isNotEmpty(name))
 375  0
                         tag.addAttribute("name", name);
 376  0
                 tag.addAttribute("value", value);
 377  0
                 tag.addAttribute("type", "hidden");
 378  0
                 return tag.toString();
 379  
         }
 380  
 }