View Javadoc

1   /*
2   * Copyright 2007 Hippo
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" 
12  * BASIS, 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 nl.hippo.portal.cms.site;
17  
18  import java.util.Iterator;
19  import java.util.Map;
20  
21  import javax.portlet.PortletRequest;
22  import javax.portlet.PortletResponse;
23  import javax.portlet.RenderRequest;
24  import javax.portlet.RenderResponse;
25  
26  import org.apache.commons.lang.StringUtils;
27  
28  import nl.hippo.client.api.content.DocumentMetadata;
29  import nl.hippo.client.api.content.DocumentPath;
30  import nl.hippo.portal.cms.CMSRequestContext;
31  
32  public class CMSLinkFactoryImpl implements CMSLinkFactory {
33  
34      public static String DOCUMENT_LINK_PATH_PREFIX = "/content/";
35      public static String ASSET_LINK_PATH_PREFIX = "/binaries/";
36      
37      CMSRequestContext context;
38  
39      public CMSLinkFactoryImpl(CMSRequestContext context) {
40          super();
41          this.context = context;
42      }
43  
44      private String getRelativePathById(String documentId){
45          DocumentMetadata metadata = context.getDefaultService().getMetaDataById(documentId);
46          if (metadata!=null){
47              return metadata.getDocumentPath().getRelativePath();
48          } else {
49              return null;
50          }
51      }
52  
53      private String rewriteSrcId(PortletRequest request, PortletResponse response, String documentId)
54      {
55          return context.getPortalURL().createPortalURL(context.getSiteMapItem().getPath(), CMSRequestContext.DOCUMENT_ID_PREFIX+documentId,(Map)null);
56      }
57  
58      private String rewriteSrcIdForSiteMapItem(PortletRequest request, PortletResponse response, SiteMapItem smi, String documentId)
59      {
60          return context.getPortalURL().createPortalURL(smi.getPath(), CMSRequestContext.DOCUMENT_ID_PREFIX+documentId,(Map)null);
61      }
62      
63      private String rewriteSitemapId(PortletRequest request, PortletResponse response, String sitemapId){
64          SiteMapItem smi = context.getSiteMapItem().getSiteMap().getById(sitemapId);
65          if (smi != null){
66              return context.getPortalURL().createPortalURL(smi.getPath()).getFullPath();
67          } 
68          return null; // sitemap id not matched
69      }
70  
71      private SiteMapItem getSiteMapItemById(String id){
72          return context.getSiteMapItem().getSiteMap().getById(id);
73      }
74      
75      private SiteMapItem getSiteMapItemByUrl(String url){
76          SiteMap sm = context.getSiteMapItem().getSiteMap();
77          return sm.getByPath(url);
78      } 
79  
80      private String normalizeUrl(String url){
81      	if (url != null){
82      		url=StringUtils.stripEnd(url, "/");
83      	}
84      	return url;
85      }
86      
87      private String rewriteSrcUrl(PortletRequest request, PortletResponse response, String srcUrl)
88      {
89          String result = null;
90          if (srcUrl != null)
91          {
92              String siteMapItemSrc = srcUrl;
93              String parameters = null;
94              int index = srcUrl.indexOf('?');
95              if (index > -1)
96              {
97                  parameters = srcUrl.substring(index + 1);
98                  siteMapItemSrc = srcUrl.substring(0, index);
99              }
100 
101             Iterator iter = context.getSite().getSiteMaps().iterator();
102             while (iter.hasNext())
103             {
104                 SiteMap sm = (SiteMap) iter.next();
105                 SiteMapItem item = sm.matchSrc(siteMapItemSrc);
106                 if (item != null)
107                 {
108                     String postfix = null;
109                     if (item.getSrc().length() + 1 < siteMapItemSrc.length())
110                     {
111                         String itemSrc = normalizeUrl(item.getSrc());
112                     	postfix = siteMapItemSrc.substring(itemSrc.length() + 1);
113                         if (postfix.toLowerCase().endsWith(".xml"))
114                         {
115                             postfix = postfix.substring(0, postfix.length() - 3) + "html";
116                         }
117                     }
118                     result = context.getPortalURL().createPortalURL(item.getPath(), postfix, parameters);
119                 }
120                 else
121                 {
122                     DocumentMetadata metaData = context.getDefaultService().getMetaData(srcUrl);
123                     if ( metaData != null && metaData.getId() != null && metaData.getType() != null )
124                     {
125                         
126                         item = sm.getById(CMSRequestContext.DOCUMENT_TYPE_SITEMAP_ID_PREFIX + metaData.getType());
127                         if ( item != null )
128                         {
129                             result = context.getPortalURL().createPortalURL(item.getPath(), CMSRequestContext.DOCUMENT_ID_PREFIX+metaData.getId(), parameters);
130                         }
131                     }
132                 }
133             }
134         }
135         return result;
136     }
137 
138     private String rewriteResourceUrl(PortletRequest request, PortletResponse response, String resourceUrl)
139     {
140         if (resourceUrl != null)
141         {
142             if (resourceUrl.length() > 0 && resourceUrl.charAt(0) == '/')
143             {
144                 resourceUrl = resourceUrl.substring(1);
145             }
146         }
147         return context.getPortalURL().getContextPath() + context.getSite().getPortalCMSResourcesPrefix() + resourceUrl;
148     }
149     
150     private boolean isInternalLink(String link){
151         return (isDocumentLink(link) || isAssetLink(link));
152     }
153 
154     private boolean isInternalIdLink(String link){
155         return (link.startsWith(INTERNAL_LINK_PREFIX+INTERNAL_LINK_ID_PREFIX));
156     }
157 
158     private boolean isDocumentLink(String link){
159         return ( (link.startsWith(INTERNAL_LINK_PREFIX) && link.substring(INTERNAL_LINK_PREFIX.length()).startsWith(DOCUMENT_LINK_PATH_PREFIX)) || link.startsWith(DOCUMENT_LINK_PATH_PREFIX) || isInternalIdLink(link));
160     }
161 
162     private boolean isAssetLink(String link){
163         return ( (link.startsWith(INTERNAL_LINK_PREFIX) && link.substring(INTERNAL_LINK_PREFIX.length()).startsWith(ASSET_LINK_PATH_PREFIX)) || link.startsWith(ASSET_LINK_PATH_PREFIX));
164     }
165 
166     private boolean isSiteMapLink(String link){
167         return (link.startsWith(SITEMAP_LINK_PREFIX));
168     }
169 
170     private boolean isSiteMapIdLink(String link){
171         return (link.startsWith(SITEMAP_LINK_PREFIX.concat(SITEMAP_ID_PREFIX)));
172     }
173 
174     private boolean isSiteMapURLLink(String link){
175         return (link.startsWith(SITEMAP_LINK_PREFIX.concat(SITEMAP_URL_PREFIX)));
176     }
177 
178     private boolean isSiteLink(String link){
179         return (link.startsWith(PORTAL_LINK_PREFIX.concat(SITE_LINK_PREFIX)));
180     }
181 
182     private boolean isPortalLink(String link){
183         return (link.startsWith(PORTAL_LINK_PREFIX));
184     }
185 
186     private boolean isExternalLink(String link){
187         return (!(isInternalLink(link)||isSiteMapLink(link)));
188     }
189     
190     private String getSiteMapItemURL(String id)
191     {
192         return getSiteMapItemURL(context.getSiteMapItem().getSiteMap().getById(id));
193     }
194 
195     public String getSiteMapItemURL(SiteMapItem item)
196     {
197         return context.getPortalURL().getSitePath() + item.getPath();
198     }
199 
200 
201     private String stripPrefix(String str, String prefix){
202         if (str.startsWith(prefix)){
203             return str.substring(prefix.length());
204         } else {
205             return str;
206         }
207     }
208 
209     private String getDocumentLinkSrc(String link){
210         if (isInternalIdLink(link)){
211             String documentId = stripPrefix(stripPrefix(link,INTERNAL_LINK_PREFIX),INTERNAL_LINK_ID_PREFIX);
212             return getRelativePathById(documentId);
213         } else {
214             return stripPrefix(link,INTERNAL_LINK_PREFIX);
215         }
216     }
217 
218     private String getAssetLinkSrc(String link){
219         return stripPrefix(link,INTERNAL_LINK_PREFIX);
220     }
221 
222     public DocumentMetadata getMetaDataForSrc(String src){
223         DocumentPath path = context.getDefaultService().createRelativePath(src);
224         return context.getDefaultService().getMetaData(path);
225     }
226     
227     private LinkItem createDocumentLinkItem(RenderRequest request, RenderResponse response, String title, String link, boolean fetchMetadata){
228         String src=getDocumentLinkSrc(link);
229         if (src != null){
230             DocumentMetadata metadata = null;
231             if (fetchMetadata){
232                 metadata = getMetaDataForSrc(src);
233             }
234             String portalUrl=rewriteSrcUrl(request, response, src);
235             if (portalUrl != null){
236             	return new LinkItemImpl(title,portalUrl,LinkItem.DOCUMENT_LINK,metadata);	
237             }             
238         } 
239         
240         return null;
241     }
242  
243     private LinkItem createAssetLinkItem(RenderRequest request, RenderResponse response, String title, String link, boolean fetchMetadata){
244         final String src=getAssetLinkSrc(link);
245         DocumentMetadata metadata = null;
246         if (fetchMetadata){
247             metadata = getMetaDataForSrc(src);
248         }
249         return new LinkItemImpl(title,rewriteResourceUrl(request, response, src),LinkItem.ASSET_LINK,metadata); 
250     }
251 
252     private LinkItem createPortalLinkItem(RenderRequest request, RenderResponse response, String title, String link, boolean fetchMetadata){
253         String finalLink;
254         if (isSiteLink(link)){
255             finalLink = stripPrefix(stripPrefix(link, PORTAL_LINK_PREFIX),SITE_LINK_PREFIX);            
256             return new LinkItemImpl(title,finalLink,LinkItem.SITE_LINK,null);
257         } else {
258             finalLink = stripPrefix(link, PORTAL_LINK_PREFIX);
259             return new LinkItemImpl(title,finalLink,LinkItem.PORTAL_LINK,null);
260         }         
261     }
262 
263 
264     private LinkItem createSiteMapLinkItem(RenderRequest request, RenderResponse response, String title, String link, boolean fetchMetadata){
265         if (isSiteMapURLLink(link)){
266             link = stripPrefix(stripPrefix(link, SITEMAP_LINK_PREFIX),SITEMAP_URL_PREFIX);
267             SiteMapItem smi = getSiteMapItemByUrl(link);
268             if (smi != null){
269                 return createLinkItem(request, response, smi, title);
270             }
271         } else
272         if (isSiteMapIdLink(link)){
273             String id = stripPrefix(stripPrefix(link, SITEMAP_LINK_PREFIX),SITEMAP_ID_PREFIX);
274             SiteMapItem smi = getSiteMapItemById(id);
275             if (smi != null){
276                 return createLinkItem(request, response, smi, title);
277             }
278         }
279         return null; 
280     }
281 
282     private LinkItem createExternalLinkItem(RenderRequest request, RenderResponse response, String title, String link, boolean fetchMetadata){
283         return new LinkItemImpl(title,link,LinkItem.EXTERNAL_LINK,null); 
284     }
285 
286     public LinkItem createLinkItem(RenderRequest request, RenderResponse response, SiteMapItem smi, String title){
287         if (title != null && title.length() > 0){
288             return new LinkItemImpl(title,getSiteMapItemURL(smi),LinkItem.SITEMAP_LINK,null);
289         }
290         else{
291             return new LinkItemImpl(smi.getTitle(),getSiteMapItemURL(smi),LinkItem.SITEMAP_LINK,null);
292         }
293     }
294     
295     public LinkItem createLinkItem(RenderRequest request, RenderResponse response, SiteMapItem smi){
296         return new LinkItemImpl(smi.getTitle(),getSiteMapItemURL(smi),LinkItem.SITEMAP_LINK,null); 
297     }
298 
299     public LinkItem createLinkItem(RenderRequest request, RenderResponse response, String title, String link, boolean fetchMetadata) {
300         if (isDocumentLink(link)){
301             return createDocumentLinkItem(request, response, title, link, fetchMetadata);
302         } else 
303         if (isAssetLink(link)){
304             return createAssetLinkItem(request, response, title, link, fetchMetadata);
305         } else 
306         if (isSiteMapLink(link)){
307             return createSiteMapLinkItem(request, response, title, link, fetchMetadata);
308         } else 
309         if (isPortalLink(link)){
310             return createPortalLinkItem(request, response, title, link, fetchMetadata);
311         } else {
312             return createExternalLinkItem(request, response, title, link, fetchMetadata);
313         }
314     }
315 
316     public LinkItem createLinkItem(RenderRequest request, RenderResponse response, String title, String link) {        
317         return createLinkItem(request,response,title,link,false);
318     }
319 
320     public LinkItem createLinkItemById(RenderRequest request, RenderResponse response, String title, String documentId, boolean fetchMetadata) {
321         // TODO Auto-generated method stub
322         return null;
323     }
324 
325     public LinkItem createLinkItemById(RenderRequest request, RenderResponse response, String title, String documentId) {
326         return createLinkItemById(request,response,title,documentId,false);
327     }
328     
329     public LinkItem createLinkItemById(RenderRequest request, RenderResponse response, String title, String documentId, String sitemapId) {
330         return createLinkItemById(request, response, title, documentId, sitemapId, false);
331     }
332 
333     public LinkItem createLinkItemById(RenderRequest request, RenderResponse response, String title, String documentId, String sitemapId, boolean fetchMetadata){
334         SiteMapItem smi = getSiteMapItemById(sitemapId);
335         if (smi != null){
336             return createLinkItemById(request,response, title, documentId, smi,fetchMetadata);
337         } else {
338             return null;
339         }        
340     }
341 
342     public LinkItem createLinkItemById(RenderRequest request, RenderResponse response, String title, String documentId, SiteMapItem smi) {
343         return createLinkItemById(request, response, title, documentId, smi, false);
344     }
345 
346     public LinkItem createLinkItemById(RenderRequest request, RenderResponse response, String title, String documentId, SiteMapItem smi, boolean fetchMetadata){
347         String url = rewriteSrcIdForSiteMapItem(request, response, smi, documentId);
348         if (title != null && title.length() > 0){
349             return new LinkItemImpl(title,url,LinkItem.DOCUMENT_LINK,null); 
350         } else {
351             return new LinkItemImpl(smi.getTitle(),url,LinkItem.DOCUMENT_LINK,null); 
352         }
353     }
354 
355 
356 
357 }