View Javadoc
1   /*
2    * Copyright 2012 Oracle Corporation. All Rights Reserved.
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  package com.fatwire.gst.foundation.mobile.action;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.commons.logging.Log;
20  
21  import COM.FutureTense.Util.ftErrors;
22  
23  import com.fatwire.assetapi.data.AssetId;
24  import com.fatwire.gst.foundation.CSRuntimeException;
25  import com.fatwire.gst.foundation.controller.AssetIdWithSite;
26  import com.fatwire.gst.foundation.controller.action.RenderPage;
27  import com.fatwire.gst.foundation.controller.annotation.InjectForRequest;
28  import com.fatwire.gst.foundation.facade.logging.LogUtil;
29  import com.fatwire.gst.foundation.facade.mda.LocaleService;
30  import com.fatwire.gst.foundation.mobile.DeviceDetector;
31  import com.fatwire.gst.foundation.mobile.DeviceType;
32  import com.fatwire.mda.DimensionFilterInstance;
33  
34  /**
35   * RenderPage action extension that handles translations as well as device
36   * detection to direct the visitor to the device specific template. </p> The
37   * rule is straight forward. If the template is X then a lookup is done if there
38   * is a Template with the name X_mobile and that is used if the visitor is using
39   * a mobile device. The same for _desktop and _tablet. If such a template does
40   * not exist, the 'normal' template is used. </p>
41   * 
42   * 
43   * @author Dolf Dijkstra
44   * 
45   */
46  public class DeviceAwareRenderPageAction extends RenderPage {
47  
48      static final private Log log = LogUtil.getLog(DeviceAwareRenderPageAction.class);
49  
50      @InjectForRequest
51      public DeviceDetector detector;
52  
53      @InjectForRequest
54      public LocaleService localeService;
55  
56      @Override
57      protected AssetIdWithSite resolveAssetId() {
58          final AssetIdWithSite id = super.resolveAssetId();
59          if (id == null || id.getSite() == null) {
60              throw new CSRuntimeException("Asset or site not found: '" + id + "' for url " + ics.pageURL(),
61                      ftErrors.pagenotfound);
62          }
63          return findTranslation(id);
64      }
65  
66      @Override
67      protected void callTemplate(AssetIdWithSite id, String tname) {
68          DeviceType type = detector.detectDeviceType(ics);
69          if (LOG.isDebugEnabled())
70              LOG.debug("detected device type: " + type);
71          String dtname = checkForDeviceTName(id, tname, type);
72          super.callTemplate(id, dtname);
73  
74      }
75  
76      @Override
77      protected void callPage(AssetIdWithSite id, String pagename, String packedArgs) {
78          DeviceType type = detector.detectDeviceType(ics);
79          if (LOG.isDebugEnabled())
80              LOG.debug("detected device type: " + type);
81          String nn = checkForDevicePagename(id, pagename, type);
82          super.callPage(id, nn, packedArgs);
83      }
84  
85      protected AssetIdWithSite findTranslation(AssetIdWithSite id) {
86          
87          if (localeService == null)
88              return id;
89          AssetIdWithSite n = id;
90          DimensionFilterInstance df = localeService.getDimensionFilter(id.getSite());
91          if (df != null) {
92              AssetId translated = localeService.findTranslation(id, df);
93              if (translated != null)
94                  n = new AssetIdWithSite(translated, id.getSite());
95  
96          }
97          return n;
98      }
99  
100     protected String getPostfix(DeviceType type) {
101         switch (type) {
102             case MOBILE:
103                 return "_mobile";
104             case TABLET:
105                 return "_tablet";
106             default:
107                 return "_desktop";
108         }
109 
110     }
111 
112     protected String checkForDeviceTName(AssetIdWithSite id, String tname, DeviceType type) {
113         if (StringUtils.endsWith(tname, "_mobile") || StringUtils.endsWith(tname, "_tablet")
114                 || StringUtils.endsWith(tname, "_desktop")) {
115             return tname;
116         }
117         String pf = getPostfix(type);
118         final String targetPagename = tname.startsWith("/") ? (id.getSite() + tname + pf) : (id.getSite() + "/"
119                 + id.getType() + "/" + tname + pf);
120         try {
121             if (ics.getPageData(targetPagename).isRegistered()) {
122                 return tname + pf;
123             } else if (LOG.isTraceEnabled()) {
124                 log.trace("There is no special template for " + type + " at template " + tname);
125             }
126         } catch (IllegalArgumentException e) {
127             LOG.warn(e.getMessage());
128             // ignore
129         }
130 
131         return tname;
132     }
133 
134     protected String checkForDevicePagename(AssetIdWithSite id, String pagename, DeviceType type) {
135         if (StringUtils.endsWith(pagename, "_mobile") || StringUtils.endsWith(pagename, "_tablet")
136                 || StringUtils.endsWith(pagename, "_desktop")) {
137             return pagename;
138         }
139         String pf = getPostfix(type);
140         final String targetPagename = pagename + pf;
141 
142         try {
143 
144             if (ics.getPageData(targetPagename).isRegistered()) {
145                 return targetPagename;
146             } else if (LOG.isTraceEnabled()) {
147                 log.trace("There is no device specific pagename for " + type + " at page " + pagename);
148             }
149         } catch (NullPointerException e) {
150             // ignore
151         } catch (IllegalArgumentException e) {
152             LOG.warn(e.getMessage());
153             // ignore
154         }
155         return pagename;
156     }
157 }