View Javadoc

1   /**
2    * Copyright (C) 2005-2009 Alfresco Software Limited.
3    *
4    * This file is part of the Spring Surf Extension project.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *  http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.springframework.extensions.webscripts;
20  
21  import java.util.HashMap;
22  import java.util.List;
23  import java.util.Map;
24  
25  import freemarker.template.TemplateBooleanModel;
26  import freemarker.template.TemplateMethodModelEx;
27  import freemarker.template.TemplateModelException;
28  import freemarker.template.TemplateNumberModel;
29  import freemarker.template.TemplateScalarModel;
30  
31  /**
32   * Custom FreeMarker Template language method.
33   * <p>
34   * Given a URL string and N named/value pairs, replace each URL argument with 
35   * respective name/value pair (if name matches existing URL argument), or add 
36   * name/value pair to URL (if name does not match existing URL argument).
37   * <p>
38   * Usage: argreplace(url.args, "skipCount", cursor.nextPage, ...)
39   *
40   * Example: argreplace("?a=0&b=2", "a", 1, "c", 3) returns "?a=1&b=2&c=3"
41   * 
42   * @author davidc
43   */
44  public final class ArgReplaceMethod implements TemplateMethodModelEx
45  {
46      
47      /**
48       * @see freemarker.template.TemplateMethodModel#exec(java.util.List)
49       */
50      public Object exec(List args) throws TemplateModelException
51      {
52          if (args.size() == 0)
53          {
54              return "";
55          }
56  
57          String urlArgs = "";
58          Object arg0 = args.get(0);
59          if (arg0 instanceof TemplateScalarModel)
60          {
61              urlArgs = ((TemplateScalarModel)arg0).getAsString();
62          }
63  
64          if (args.size() == 1)
65          {
66              return urlArgs;
67          }
68          
69          Map<String, String> replacements = new HashMap<String, String>();
70          int i = 1;
71          while(i < args.size())
72          {
73              String name = null;
74              String val = null;
75              Object argname = args.get(i);
76              if (argname instanceof TemplateScalarModel)
77              {
78                  name = ((TemplateScalarModel)argname).getAsString();
79                  i++;
80                  if (i < args.size())
81                  {
82                      Object argval = args.get(i);
83                      if (argval instanceof TemplateScalarModel)
84                      {
85                          val = ((TemplateScalarModel)argval).getAsString();
86                      }
87                      else if (argval instanceof TemplateNumberModel)
88                      {
89                          val = ((TemplateNumberModel)argval).getAsNumber().toString();
90                      }
91                      else if (argval instanceof TemplateBooleanModel)
92                      {
93                          val = Boolean.toString(((TemplateBooleanModel)argval).getAsBoolean());
94                      }
95  
96                      if (val != null)
97                      {
98                          replacements.put(name, val);
99                      }
100                 }
101             }
102             i++;
103         }
104 
105         if (replacements.size() == 0)
106         {
107             return urlArgs;
108         }
109         
110         StringBuilder newUrlArgs = new StringBuilder();
111         if (urlArgs.length() > 0)
112         {
113             String[] argPairs = urlArgs.split("&");
114             int n = 0;
115             for (String argPair : argPairs)
116             {
117                 String[] nameVal = argPair.split("=");
118                 String name = nameVal[0];
119                 String val = (nameVal.length > 1) ? nameVal[1] : null;
120                 String replaceVal = replacements.get(name);
121                 if (replaceVal != null)
122                 {
123                     val = replaceVal; 
124                 }
125                 newUrlArgs.append(name);
126                 if (val != null)
127                 {
128                     newUrlArgs.append("=");
129                     newUrlArgs.append(val);
130                     replacements.remove(name);
131                 }
132                 n++;
133                 if (n < argPairs.length || replacements.size() > 0)
134                 {
135                     newUrlArgs.append("&");
136                 }
137             }
138         }
139 
140         int rs = replacements.entrySet().size();
141         int r = 0;
142         for (Map.Entry<String, String> replacement : replacements.entrySet())
143         {
144             newUrlArgs.append(replacement.getKey());
145             if (replacement.getValue() != null)
146             {
147                 newUrlArgs.append("=");
148                 newUrlArgs.append(replacement.getValue());
149                 r++;
150                 if (r < rs)
151                 {
152                     newUrlArgs.append("&");
153                 }
154             }
155         }
156         
157         return newUrlArgs;    
158     }
159 }