1   /*
2    * Copyright 2000-2001,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* 
18  
19   */
20  
21  package org.apache.wsrp4j.producer.provider.driver;
22  
23  import java.net.URLEncoder;
24  
25  import oasis.names.tc.wsrp.v1.types.PortletContext;
26  import oasis.names.tc.wsrp.v1.types.RuntimeContext;
27  import oasis.names.tc.wsrp.v1.types.Templates;
28  import oasis.names.tc.wsrp.v1.types.UserContext;
29  
30  import org.apache.wsrp4j.exception.ErrorCodes;
31  import org.apache.wsrp4j.exception.WSRPException;
32  import org.apache.wsrp4j.exception.WSRPXHelper;
33  import org.apache.wsrp4j.log.LogManager;
34  import org.apache.wsrp4j.log.Logger;
35  import org.apache.wsrp4j.producer.provider.Provider;
36  import org.apache.wsrp4j.producer.provider.URLComposer;
37  import org.apache.wsrp4j.util.Constants;
38  
39  /**
40   * <p>This class implements the URLComposer interface providing methods to generate
41   * URLs or namespace tokens.</p>
42   * <p>There are two kinds of methods:
43   * <ul>
44   *   <li>Methods defining URLs or tokens to be rewritten by the consumer.</li>
45   *   <li>Methods defining complete URLs or namespaced tokens according to the
46   *       templates delivered by the Consumer.</li></p> 
47   *
48   * @author <a href="mailto:stefan.behl@de.ibm.com">Stefan Behl</a>
49   */
50  public class URLComposerImpl implements URLComposer {
51      // the provider implementation
52      private Provider provider = null;
53  
54      // for logging and exception support
55      private Logger logger = LogManager.getLogManager().getLogger(
56              this.getClass());
57  
58      private URLComposerImpl() {
59      }
60  
61      public static URLComposerImpl getInstance(Provider provider) {
62          URLComposerImpl urlComposer = new URLComposerImpl();
63          urlComposer.provider = provider;
64  
65          return urlComposer;
66      }
67  
68      // methods generating rewrite urls
69  
70      /**
71       * creates a rewrite blocking-action-url
72       * 
73       * @param portletMode
74       * @param navigationalState
75       * @param interactionState
76       * @param windowState
77       * @param secureURL
78       * @param runtimeContext
79       * @param portletContext
80       * @param userContext
81       * 
82       * @return URL as String
83       */
84      public String createBlockingActionURL(String portletMode,
85              String navigationalState, String interactionState,
86              String windowState, boolean secureURL,
87              RuntimeContext runtimeContext, PortletContext portletContext,
88              UserContext userContext) {
89          String MN = "createBlockingActionURL";
90          if (logger.isLogging(Logger.TRACE_HIGH)) {
91              logger.entry(Logger.TRACE_HIGH, MN);
92          }
93  
94          // check if valid templates are provided
95          if (runtimeContext != null) {
96  
97              Templates templates = runtimeContext.getTemplates();
98              if (templates != null) {
99  
100                 String template = null;
101                 if (secureURL) {
102 
103                     template = templates.getSecureBlockingActionTemplate();
104                     if (template == null)
105                         template = templates.getSecureDefaultTemplate();
106 
107                 }
108                 else {
109 
110                     template = templates.getBlockingActionTemplate();
111                     if (template == null)
112                         template = templates.getDefaultTemplate();
113                 }
114 
115                 try {
116                     if (template != null) {
117 
118                         if (logger.isLogging(Logger.TRACE_HIGH)) {
119                             logger.exit(Logger.TRACE_HIGH, MN);
120                         }
121 
122                         return this.createBlockingActionURLByTemplate(template,
123                                 portletMode, navigationalState,
124                                 interactionState, windowState,
125                                 portletContext == null ? null : portletContext
126                                         .getPortletHandle(),
127                                 userContext == null ? null : userContext
128                                         .getUserContextKey(), runtimeContext
129                                         .getPortletInstanceKey(),
130                                 runtimeContext.getSessionID());
131                     }
132                 }
133                 catch (WSRPException e) {
134 
135                     // TODO: pass exception to consumer
136                 }
137             }
138         }
139 
140         if (logger.isLogging(Logger.TRACE_HIGH)) {
141             logger.exit(Logger.TRACE_HIGH, MN);
142         }
143 
144         return createRewriteURL(Constants.URL_TYPE_BLOCKINGACTION, portletMode,
145                 navigationalState, interactionState, windowState, null, null,
146                 null, java.lang.String.valueOf(secureURL));
147     }
148 
149     /**
150      * creates a rewrite render-url
151      */
152     public String createRenderURL(String portletMode, String navigationalState,
153             String windowState, boolean secureURL,
154             RuntimeContext runtimeContext, PortletContext portletContext,
155             UserContext userContext) {
156         String MN = "createRenderURL";
157         if (logger.isLogging(Logger.TRACE_HIGH)) {
158             logger.entry(Logger.TRACE_HIGH, MN);
159         }
160 
161         // check if valid templates are provided
162         if (runtimeContext != null) {
163 
164             Templates templates = runtimeContext.getTemplates();
165             if (templates != null) {
166 
167                 String template = null;
168                 if (secureURL) {
169 
170                     template = templates.getSecureRenderTemplate();
171                     if (template == null)
172                         template = templates.getDefaultTemplate();
173 
174                 }
175                 else {
176 
177                     template = templates.getRenderTemplate();
178                     if (template == null)
179                         template = templates.getDefaultTemplate();
180                 }
181 
182                 try {
183                     if (template != null) {
184 
185                         if (logger.isLogging(Logger.TRACE_HIGH)) {
186                             logger.exit(Logger.TRACE_HIGH, MN);
187                         }
188 
189                         return this.createRenderURLByTemplate(template,
190                                 portletMode, navigationalState, windowState,
191                                 portletContext == null ? null : portletContext
192                                         .getPortletHandle(),
193                                 userContext == null ? null : userContext
194                                         .getUserContextKey(), runtimeContext
195                                         .getPortletInstanceKey(),
196                                 runtimeContext.getSessionID());
197                     }
198                 }
199                 catch (WSRPException e) {
200 
201                     // TODO: pass exception to consumer
202 
203                 }
204             }
205         }
206 
207         if (logger.isLogging(Logger.TRACE_HIGH)) {
208             logger.exit(Logger.TRACE_HIGH, MN);
209         }
210 
211         return createRewriteURL(Constants.URL_TYPE_RENDER, portletMode,
212                 navigationalState, null, windowState, null, null, null,
213                 java.lang.String.valueOf(secureURL));
214     }
215 
216     /**
217      * creates a rewrite resource-url
218      */
219     public String createResourceURL(String url, boolean rewriteResource,
220             boolean secureURL, RuntimeContext runtimeContext,
221             PortletContext portletContext, UserContext userContext) {
222         String MN = "createResourceURL";
223         if (logger.isLogging(Logger.TRACE_HIGH)) {
224             logger.entry(Logger.TRACE_HIGH, MN);
225         }
226 
227         // check if valid templates are provided
228         if (runtimeContext != null) {
229 
230             Templates templates = runtimeContext.getTemplates();
231             if (templates != null) {
232 
233                 String template = null;
234                 if (secureURL) {
235 
236                     template = templates.getSecureResourceTemplate();
237                     if (template == null)
238                         template = templates.getDefaultTemplate();
239 
240                 }
241                 else {
242 
243                     template = templates.getResourceTemplate();
244                     if (template == null)
245                         template = templates.getDefaultTemplate();
246                 }
247 
248                 try {
249                     if (template != null) {
250 
251                         if (logger.isLogging(Logger.TRACE_HIGH)) {
252                             logger.exit(Logger.TRACE_HIGH, MN);
253                         }
254 
255                         return this.createResourceURLByTemplate(template, url,
256                                 rewriteResource, portletContext == null ? null
257                                         : portletContext.getPortletHandle(),
258                                 userContext == null ? null : userContext
259                                         .getUserContextKey(), runtimeContext
260                                         .getPortletInstanceKey(),
261                                 runtimeContext.getSessionID());
262                     }
263 
264                 }
265                 catch (WSRPException e) {
266 
267                     // TODO: pass exception to consumer
268 
269                 }
270             }
271         }
272 
273         if (logger.isLogging(Logger.TRACE_HIGH)) {
274             logger.exit(Logger.TRACE_HIGH, MN);
275         }
276 
277         return createRewriteURL(Constants.URL_TYPE_RESOURCE, null, null, null,
278                 null, url, java.lang.String.valueOf(rewriteResource), null,
279                 java.lang.String.valueOf(secureURL));
280     }
281 
282     /**
283      * creates a namespaced token
284      */
285     public String createNamespacedToken(String token,
286             RuntimeContext runtimeContext) {
287         String MN = "createNamespacedToken";
288         if (logger.isLogging(Logger.TRACE_HIGH)) {
289             logger.entry(Logger.TRACE_HIGH, MN);
290         }
291 
292         String nsToken = null;
293 
294         // first get the prefix
295         // this is either the prefix passed in the RuntimeContext
296         if (runtimeContext != null) {
297             nsToken = runtimeContext.getNamespacePrefix();
298         }
299         // no namespace prefix obtained?
300         // then need to put in the rewrite NS wsrp_rewrite_ 
301         if (nsToken == null) {
302             nsToken = Constants.REWRITE_START + Constants.NAMESPACE_START;
303         }
304 
305         // append the token
306         // if token is null, simply return the namespace
307         if (token != null) {
308             nsToken = nsToken.concat(token);
309         }
310 
311         if (logger.isLogging(Logger.TRACE_HIGH)) {
312             logger.exit(Logger.TRACE_HIGH, MN);
313         }
314 
315         return nsToken;
316     }
317 
318     private String createRewriteURL(String urlType, String portletMode,
319             String navigationalState, String interactionState,
320             String windowState, String url, String rewriteResource,
321             String token, String secureURL) {
322 
323         String MN = "createRewriteURL()";
324         if (logger.isLogging(Logger.TRACE_HIGH)) {
325             logger.entry(Logger.TRACE_HIGH, MN, new Object[] { urlType,
326                     portletMode, navigationalState, interactionState,
327                     windowState, url, rewriteResource, token, secureURL });
328         }
329 
330         StringBuffer resultURL = new StringBuffer();
331 
332         resultURL.append(Constants.REWRITE_START);
333         resultURL.append(Constants.PARAMS_START);
334 
335         // urlType must be first (required)
336         if (urlType != null) {
337             resultURL.append(appendNameValuePair(Constants.URL_TYPE, urlType));
338         }
339         else {
340 
341             //TODO: Error
342         }
343 
344         // portletMode
345         if (portletMode != null && portletMode.length() > 0) {
346             resultURL.append(Constants.NEXT_PARAM_AMP);
347             resultURL.append(appendNameValuePair(Constants.PORTLET_MODE,
348                     portletMode));
349         }
350 
351         // navigationalState
352         if (navigationalState != null && navigationalState.length() > 0) {
353             resultURL.append(Constants.NEXT_PARAM_AMP);
354             resultURL.append(appendNameValuePair(Constants.NAVIGATIONAL_STATE,
355                     navigationalState));
356         }
357 
358         // interactionState
359         if (interactionState != null && interactionState.length() > 0) {
360             resultURL.append(Constants.NEXT_PARAM_AMP);
361             resultURL.append(appendNameValuePair(Constants.INTERACTION_STATE,
362                     interactionState));
363         }
364 
365         // windowState
366         if (windowState != null && windowState.length() > 0) {
367             resultURL.append(Constants.NEXT_PARAM_AMP);
368             resultURL.append(appendNameValuePair(Constants.WINDOW_STATE,
369                     windowState));
370         }
371 
372         // url
373         if (url != null && url.length() > 0) {
374             resultURL.append(Constants.NEXT_PARAM_AMP);
375             String fileEncoding = System.getProperty("file.encoding", "UTF-8");
376             try {
377                 resultURL.append(appendNameValuePair(Constants.URL, URLEncoder
378                         .encode(url, fileEncoding)));
379             }
380             catch (Exception e) {
381                 logger.text(Logger.ERROR, MN, e, "Encoding not supported.");
382             }
383         }
384 
385         // rewriteResource
386         if (rewriteResource != null && rewriteResource.length() > 0) {
387             resultURL.append(Constants.NEXT_PARAM_AMP);
388             resultURL.append(appendNameValuePair(Constants.REWRITE_RESOURCE,
389                     rewriteResource));
390         }
391 
392         // secureURL
393         if (secureURL != null && secureURL.length() > 0) {
394             resultURL.append(Constants.NEXT_PARAM_AMP);
395             resultURL.append(appendNameValuePair(Constants.SECURE_URL,
396                     secureURL));
397         }
398 
399         resultURL.append(Constants.REWRITE_END);
400 
401         if (logger.isLogging(Logger.TRACE_HIGH)) {
402             logger.exit(Logger.TRACE_HIGH, MN);
403         }
404 
405         String result = resultURL.toString();
406 
407         if (logger.isLogging(Logger.TRACE_HIGH)) {
408             logger.exit(Logger.TRACE_HIGH, MN, result);
409         }
410 
411         return result;
412 
413     }
414 
415     private String createNameValuePair(String name, String value) {
416 
417         StringBuffer pair = new StringBuffer(name);
418         pair.append(Constants.EQUALS);
419         pair.append(value);
420 
421         return pair.toString();
422     }
423 
424     private String appendNameValuePair(String name, String value) {
425         return createNameValuePair(name, value);
426     }
427 
428     // methods generating urls by template processing
429 
430     private String createBlockingActionURLByTemplate(
431             String blockingActionTemplate, String portletMode,
432             String navigationalState, String interactionState,
433             String windowState) throws WSRPException {
434 
435         return processTemplate(blockingActionTemplate,
436                 Constants.URL_TYPE_BLOCKINGACTION, portletMode,
437                 navigationalState, interactionState, windowState, null, null,
438                 null, null, null, null);
439 
440     }
441 
442     private String createBlockingActionURLByTemplate(
443             String blockingActionTemplate, String portletMode,
444             String navigationalState, String interactionState,
445             String windowState, String portletHandle, String userContextKey,
446             String portletInstanceKey, String sessionID) throws WSRPException {
447 
448         return processTemplate(blockingActionTemplate,
449                 Constants.URL_TYPE_BLOCKINGACTION, portletMode,
450                 navigationalState, interactionState, windowState, null, null,
451                 portletHandle, userContextKey, portletInstanceKey, sessionID);
452 
453     }
454 
455     private String createRenderURLByTemplate(String renderTemplate,
456             String portletMode, String navigationalState, String windowState)
457             throws WSRPException {
458 
459         return processTemplate(renderTemplate, Constants.URL_TYPE_RENDER,
460                 portletMode, navigationalState, null, windowState, null, null,
461                 null, null, null, null);
462     }
463 
464     private String createRenderURLByTemplate(String renderTemplate,
465             String portletMode, String navigationalState, String windowState,
466             String portletHandle, String userContextKey,
467             String portletInstanceKey, String sessionID) throws WSRPException {
468 
469         return processTemplate(renderTemplate, Constants.URL_TYPE_RENDER,
470                 portletMode, navigationalState, null, windowState, null, null,
471                 portletHandle, userContextKey, portletInstanceKey, sessionID);
472 
473     }
474 
475     private String createResourceURLByTemplate(String resourceTemplate,
476             String url, boolean rewriteResource) throws WSRPException {
477 
478         return processTemplate(resourceTemplate, Constants.URL_TYPE_RESOURCE,
479                 null, null, null, null, url, java.lang.String
480                         .valueOf(rewriteResource), null, null, null, null);
481 
482     }
483 
484     private String createResourceURLByTemplate(String resourceTemplate,
485             String url, boolean rewriteResource, String portletHandle,
486             String userContextKey, String portletInstanceKey, String sessionID)
487             throws WSRPException {
488 
489         return processTemplate(resourceTemplate, Constants.URL_TYPE_RESOURCE,
490                 null, null, null, null, url, java.lang.String
491                         .valueOf(rewriteResource), portletHandle,
492                 userContextKey, portletInstanceKey, sessionID);
493 
494     }
495 
496     private String processTemplate(String template, String urlType,
497             String portletMode, String navigationalState,
498             String interactionState, String windowState, String url,
499             String rewriteResource, String portletHandle,
500             String userContextKey, String portletInstanceKey, String sessionID)
501             throws WSRPException {
502 
503         String MN = "processTemplate";
504         if (logger.isLogging(Logger.TRACE_HIGH)) {
505             logger.entry(Logger.TRACE_HIGH, MN);
506         }
507 
508         String replaceToken = "";
509 
510         // Any template containing "{" or "}" will be processed.
511         while ((template.indexOf(Constants.REPLACE_START) != -1)
512                 | (template.indexOf(Constants.REPLACE_END) != -1)) {
513 
514             StringBuffer templateBuffer = new StringBuffer(template);
515 
516             // get positions of next left and right brackets
517             int left_br = template.indexOf(Constants.REPLACE_START);
518             int right_br = template.indexOf(Constants.REPLACE_END) + 1;
519 
520             // check if bracketing is correct 
521             if ((left_br > right_br) | (left_br == -1) | (right_br == -1)) {
522 
523                 WSRPXHelper.throwX(logger, Logger.ERROR, MN,
524                         ErrorCodes.SYNTAX_ERROR_IN_TEMPLATE);
525 
526             }
527 
528             // get replaceToken without curly brackets enclosing it
529             replaceToken = templateBuffer.substring(left_br + 1, right_br - 1);
530 
531             // urlType
532             if (replaceToken.equalsIgnoreCase(Constants.URL_TYPE)) {
533                 if (urlType == null) {
534                     urlType = "";
535                 }
536                 templateBuffer.replace(left_br, right_br, urlType);
537             }
538 
539             // portletMode
540             else if (replaceToken.equalsIgnoreCase(Constants.PORTLET_MODE)) {
541                 if (portletMode == null) {
542                     portletMode = "";
543                 }
544                 templateBuffer.replace(left_br, right_br, portletMode);
545             }
546 
547             // navigationalState
548             else if (replaceToken
549                     .equalsIgnoreCase(Constants.NAVIGATIONAL_STATE)) {
550                 if (navigationalState == null) {
551                     navigationalState = "";
552                 }
553                 templateBuffer.replace(left_br, right_br, navigationalState);
554             }
555 
556             // interactionState
557             else if (replaceToken.equalsIgnoreCase(Constants.INTERACTION_STATE)) {
558                 if (interactionState == null) {
559                     interactionState = "";
560                 }
561                 templateBuffer.replace(left_br, right_br, interactionState);
562             }
563 
564             // windowState
565             else if (replaceToken.equalsIgnoreCase(Constants.WINDOW_STATE)) {
566                 if (windowState == null) {
567                     windowState = "";
568                 }
569                 templateBuffer.replace(left_br, right_br, windowState);
570             }
571 
572             // url
573             else if (replaceToken.equalsIgnoreCase(Constants.URL)) {
574                 if (url == null) {
575                     url = "";
576                 }
577                 templateBuffer.replace(left_br, right_br, url);
578             }
579 
580             // rewriteResource
581             else if (replaceToken.equalsIgnoreCase(Constants.REWRITE_RESOURCE)) {
582                 if (rewriteResource == null) {
583                     rewriteResource = "";
584                 }
585                 templateBuffer.replace(left_br, right_br, rewriteResource);
586             }
587 
588             /*
589              
590              // secureURL
591              else if (replaceToken.equalsIgnoreCase(Constants.SECURE_URL))
592              {
593              if (secureURL == null)
594              {
595              secureURL = "";
596              }
597              templateBuffer.replace(left_br, right_br, secureURL);
598              }
599              
600              // token
601              else if (replaceToken.equalsIgnoreCase(Constants.TOKEN))
602              {
603              if (token == null)
604              {
605              token = "";
606              }
607              templateBuffer.replace(left_br, right_br, token);
608              }
609              */
610             // portletHandle
611             else if (replaceToken.equalsIgnoreCase(Constants.PORTLET_HANDLE)) {
612                 if (portletHandle == null) {
613                     portletHandle = "";
614                 }
615                 templateBuffer.replace(left_br, right_br, portletHandle);
616             }
617 
618             // userContextKey
619             else if (replaceToken.equalsIgnoreCase(Constants.USER_CONTEXT_KEY)) {
620                 if (userContextKey == null) {
621                     userContextKey = "";
622                 }
623                 templateBuffer.replace(left_br, right_br, userContextKey);
624             }
625 
626             // portletInstanceKey
627             else if (replaceToken
628                     .equalsIgnoreCase(Constants.PORTLET_INSTANCE_KEY)) {
629                 if (portletInstanceKey == null) {
630                     portletInstanceKey = "";
631                 }
632                 templateBuffer.replace(left_br, right_br, portletInstanceKey);
633             }
634 
635             // sessionID
636             else if (replaceToken.equalsIgnoreCase(Constants.SESSION_ID)) {
637                 if (sessionID == null) {
638                     sessionID = "";
639                 }
640                 templateBuffer.replace(left_br, right_br, sessionID);
641             }
642 
643             // unknown
644             else {
645 
646                 WSRPXHelper.throwX(logger, Logger.ERROR, MN,
647                         ErrorCodes.UNKNOWN_TOKEN_IN_TEMPLATE);
648 
649             }
650 
651             // update template
652             template = templateBuffer.toString();
653 
654         }
655 
656         if (logger.isLogging(Logger.TRACE_HIGH)) {
657             logger.exit(Logger.TRACE_HIGH, MN);
658         }
659 
660         return template;
661     }
662 
663 }