1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  package org.primefaces.extensions.component.documentviewer;
23  
24  import java.io.IOException;
25  import java.net.URLEncoder;
26  import java.nio.charset.StandardCharsets;
27  import java.util.ArrayList;
28  import java.util.List;
29  import java.util.Objects;
30  
31  import javax.faces.application.Resource;
32  import javax.faces.application.ResourceHandler;
33  import javax.faces.component.UIComponent;
34  import javax.faces.context.FacesContext;
35  import javax.faces.context.ResponseWriter;
36  
37  import org.primefaces.context.PrimeRequestContext;
38  import org.primefaces.extensions.util.Attrs;
39  import org.primefaces.extensions.util.ExtLangUtils;
40  import org.primefaces.model.StreamedContent;
41  import org.primefaces.renderkit.CoreRenderer;
42  import org.primefaces.util.Constants;
43  import org.primefaces.util.DynamicContentSrcBuilder;
44  import org.primefaces.util.LangUtils;
45  import org.primefaces.util.Lazy;
46  
47  
48  
49  
50  
51  
52  
53  
54  public class DocumentViewerRenderer extends CoreRenderer {
55  
56      @Override
57      public void encodeEnd(final FacesContext context, final UIComponent component) throws IOException {
58          boolean hideResourceVersion = PrimeRequestContext.getCurrentInstance(context).isHideResourceVersion();
59          if (hideResourceVersion) {
60              logDevelopmentWarning(context, "DocumentViewer requires a resource version to work properly and '" +
61                          Constants.ContextParams.HIDE_RESOURCE_VERSION + "' is currently configured.");
62          }
63  
64          final DocumentViewer documentViewer = (DocumentViewer) component;
65          encodeMarkup(context, documentViewer);
66      }
67  
68      private void encodeMarkup(final FacesContext context, final DocumentViewer documentViewer) throws IOException {
69          
70          String title = documentViewer.getTitle() != null ? documentViewer.getTitle() : documentViewer.getName();
71          title = ExtLangUtils.defaultString(title, "Document Viewer");
72  
73          final ResponseWriter writer = context.getResponseWriter();
74          writer.startElement("iframe", documentViewer);
75          writer.writeAttribute("id", documentViewer.getClientId(), null);
76          writer.writeAttribute(Attrs.STYLE, documentViewer.getStyle(), null);
77          writer.writeAttribute("title", title, null);
78          writer.writeAttribute("width", documentViewer.getWidth() != null ? documentViewer.getWidth() : "100%", null);
79          writer.writeAttribute("height", documentViewer.getHeight(), null);
80          writer.writeAttribute("allowfullscreen", Constants.EMPTY_STRING, null);
81          writer.writeAttribute("webkitallowfullscreen", Constants.EMPTY_STRING, null);
82          writer.writeAttribute("src", generateSrc(context, documentViewer), null);
83          writer.endElement("iframe");
84      }
85  
86      private String generateSrc(final FacesContext context, final DocumentViewer documentViewer) throws IOException {
87          final String imageSrc;
88          try {
89              imageSrc = URLEncoder.encode(getDocumentSource(context, documentViewer), StandardCharsets.UTF_8);
90          }
91          catch (final Exception ex) {
92              throw new IOException(ex);
93          }
94  
95          return getResourceURL(context) +
96                      "&file=" +
97                      imageSrc +
98                      generateHashString(documentViewer);
99      }
100 
101     private String generateHashString(final DocumentViewer documentViewer) {
102         final List<String> params = new ArrayList<>(4);
103         params.add("locale=" + documentViewer.calculateLocale().toString().replace('_', '-'));
104 
105         
106         if (documentViewer.getPage() != null) {
107             params.add("page=" + documentViewer.getPage());
108         }
109 
110         
111         
112         if (LangUtils.isNotBlank(documentViewer.getZoom())) {
113             params.add("zoom=" + documentViewer.getZoom());
114         }
115 
116         
117         if (LangUtils.isNotBlank(documentViewer.getNameddest())) {
118             params.add("nameddest=" + documentViewer.getNameddest());
119         }
120 
121         
122         if (LangUtils.isNotBlank(documentViewer.getPagemode())) {
123             params.add("pagemode=" + documentViewer.getPagemode());
124         }
125 
126         params.add("disableFontFace=" + documentViewer.isDisableFontFace());
127 
128         return "#" + String.join("&", params.toArray(new String[0]));
129     }
130 
131     private String getResourceURL(final FacesContext context) {
132         final ResourceHandler handler = context.getApplication().getResourceHandler();
133         return context.getExternalContext().encodeResourceURL(
134                     handler.createResource("documentviewer/pdfviewer.html", "primefaces-extensions").getRequestPath());
135     }
136 
137     protected String getDocumentSource(final FacesContext context, final DocumentViewer documentViewer) {
138         final String name = documentViewer.getName();
139 
140         if (name != null) {
141             final String libName = documentViewer.getLibrary();
142             final ResourceHandler handler = context.getApplication().getResourceHandler();
143             final Resource res = handler.createResource(name, libName);
144 
145             if (res == null) {
146                 return "RES_NOT_FOUND";
147             }
148             else {
149                 final String requestPath = res.getRequestPath();
150                 return context.getExternalContext().encodeResourceURL(requestPath);
151             }
152         }
153         else {
154             final Object value = documentViewer.getValue();
155             String downloadName = documentViewer.getDownload();
156             if (value instanceof StreamedContent) {
157                 final StreamedContent streamedContent = (StreamedContent) value;
158                 downloadName = Objects.toString(streamedContent.getName(), downloadName);
159             }
160             return DynamicContentSrcBuilder.build(context,
161                         documentViewer,
162                         documentViewer.getValueExpression("value"),
163                         new Lazy<>(() -> value),
164                         documentViewer.isCache(),
165                         true) + "&download=" + downloadName;
166         }
167     }
168 }