View Javadoc
1   /**
2    * Copyright 2011-2019 PrimeFaces Extensions
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 org.primefaces.extensions.component.exporter;
17  
18  import java.io.IOException;
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import javax.el.MethodExpression;
23  import javax.faces.component.EditableValueHolder;
24  import javax.faces.component.UIComponent;
25  import javax.faces.component.UIData;
26  import javax.faces.component.ValueHolder;
27  import javax.faces.component.html.HtmlCommandButton;
28  import javax.faces.component.html.HtmlCommandLink;
29  import javax.faces.component.html.HtmlGraphicImage;
30  import javax.faces.component.html.HtmlOutputLink;
31  import javax.faces.component.html.HtmlSelectOneMenu;
32  import javax.faces.context.FacesContext;
33  import javax.faces.convert.Converter;
34  import javax.faces.event.ActionEvent;
35  
36  import org.primefaces.component.api.DynamicColumn;
37  import org.primefaces.component.api.UIColumn;
38  import org.primefaces.component.celleditor.CellEditor;
39  import org.primefaces.component.column.Column;
40  import org.primefaces.component.datalist.DataList;
41  import org.primefaces.component.datatable.DataTable;
42  import org.primefaces.component.roweditor.RowEditor;
43  import org.primefaces.component.subtable.SubTable;
44  import org.primefaces.util.ComponentUtils;
45  import org.primefaces.util.Constants;
46  
47  /**
48   * <code>Exporter</code> component.
49   *
50   * @author Sudheer Jonna / last modified by $Author$
51   * @since 0.7.0
52   */
53  public abstract class Exporter {
54  
55      protected String skipComponents;
56  
57      protected enum ColumnType {
58          HEADER("header"), FOOTER("footer");
59  
60          private final String facet;
61  
62          ColumnType(final String facet) {
63              this.facet = facet;
64          }
65  
66          public String facet() {
67              return facet;
68          }
69  
70          @Override
71          public String toString() {
72              return facet;
73          }
74      }
75  
76      public abstract void export(ActionEvent event, String tableId, FacesContext facesContext,
77                  String outputFileName, String tableTitleValue, boolean pageOnly, boolean selectionOnly,
78                  String encodingType, MethodExpression preProcessor,
79                  MethodExpression postProcessor, boolean subTable) throws IOException;
80  
81      public abstract void customFormat(String facetBackground, String facetFontSize, String facetFontColor, String facetFontStyle, String fontName,
82                  String cellFontSize, String cellFontColor, String cellFontStyle, String datasetPadding, String orientation) throws IOException;
83  
84      protected String exportColumnByFunction(final FacesContext context, final UIColumn column) {
85          final MethodExpression exportFunction = column.getExportFunction();
86  
87          if (exportFunction != null) {
88              return (String) exportFunction.invoke(context.getELContext(), new Object[] {column});
89          }
90  
91          return Constants.EMPTY_STRING;
92      }
93  
94      protected String exportValue(final FacesContext context, final UIComponent component) {
95  
96          if (component instanceof CellEditor) {
97              return exportValue(context, component.getFacet("output"));
98          }
99          if (component instanceof RowEditor) {
100             return "RowEditor";
101         }
102 
103         if (component instanceof HtmlGraphicImage) {
104             return (String) component.getAttributes().get("alt");
105         }
106 
107         if (component instanceof HtmlCommandLink) {
108             final HtmlCommandLink link = (HtmlCommandLink) component;
109             final Object value = link.getValue();
110 
111             if (value != null) {
112                 return String.valueOf(value);
113             }
114             else {
115                 // export first value holder
116                 for (final UIComponent child : link.getChildren()) {
117                     if (child instanceof ValueHolder) {
118                         return exportValue(context, child);
119                     }
120                 }
121 
122                 return Constants.EMPTY_STRING;
123             }
124         }
125         if (component instanceof HtmlOutputLink) {
126             final HtmlOutputLink link = (HtmlOutputLink) component;
127 
128             final List<UIComponent> children = link.getChildren();
129             if (children != null) {
130                 return exportValue(context, children.get(0));
131             }
132         }
133         if (component instanceof HtmlCommandButton) {
134             final HtmlCommandButton button = (HtmlCommandButton) component;
135             final Object value = button.getValue();
136 
137             if (value != null) {
138                 return String.valueOf(value);
139             }
140             else {
141                 // export first value holder
142                 for (final UIComponent child : button.getChildren()) {
143                     if (child instanceof ValueHolder) {
144                         return exportValue(context, child);
145                     }
146                 }
147 
148                 return Constants.EMPTY_STRING;
149             }
150         }
151         if (component instanceof HtmlSelectOneMenu) {
152             final HtmlSelectOneMenu oneMenu = (HtmlSelectOneMenu) component;
153             final Object value = oneMenu.getSubmittedValue();
154 
155             if (value != null) {
156                 return String.valueOf(value);
157             }
158             else {
159                 // export first value holder
160                 for (final UIComponent child : oneMenu.getChildren()) {
161                     if (child instanceof ValueHolder) {
162                         return exportValue(context, child);
163                     }
164                 }
165 
166                 return Constants.EMPTY_STRING;
167             }
168         }
169         if (skipComponents.contains(component.getClass().getName())) {
170             return Constants.EMPTY_STRING;
171         }
172         else if (component instanceof ValueHolder) {
173 
174             if (component instanceof EditableValueHolder) {
175                 final Object submittedValue = ((EditableValueHolder) component).getSubmittedValue();
176                 if (submittedValue != null) {
177                     return submittedValue.toString();
178                 }
179             }
180 
181             final ValueHolder valueHolder = (ValueHolder) component;
182             final Object value = valueHolder.getValue();
183             if (value == null) {
184                 return Constants.EMPTY_STRING;
185             }
186 
187             // first ask the converter
188             if (valueHolder.getConverter() != null) {
189                 return valueHolder.getConverter().getAsString(context, component, value);
190             }
191             // Try to guess
192             else {
193                 final Converter converterForType = ComponentUtils.getConverter(context, component);
194                 if (converterForType != null) {
195                     return converterForType.getAsString(context, component, value);
196                 }
197             }
198 
199             // No converter found just return the value as string
200             return value.toString();
201         }
202         else {
203             // This would get the plain texts on UIInstructions when using Facelets
204             final String value = component.toString();
205             return value.trim();
206         }
207     }
208 
209     protected String exportFacetValue(final FacesContext context, final UIComponent component) {
210         if (component instanceof ValueHolder) {
211 
212             if (component instanceof EditableValueHolder) {
213                 final Object submittedValue = ((EditableValueHolder) component).getSubmittedValue();
214                 if (submittedValue != null) {
215                     return submittedValue.toString();
216                 }
217             }
218 
219             final ValueHolder valueHolder = (ValueHolder) component;
220             final Object value = valueHolder.getValue();
221             if (value == null) {
222                 return Constants.EMPTY_STRING;
223             }
224 
225             // first ask the converter
226             if (valueHolder.getConverter() != null) {
227                 return valueHolder.getConverter().getAsString(context, component, value);
228             }
229             return value.toString();
230         }
231         else {
232             // This would get the plain texts on UIInstructions when using Facelets
233             final String value = component.toString();
234 
235             return value.trim();
236         }
237 
238     }
239 
240     protected List<UIColumn> getColumnsToExport(final UIData table) {
241         final List<UIColumn> columns = new ArrayList<UIColumn>();
242 
243         for (final UIComponent child : table.getChildren()) {
244             if (child instanceof UIColumn) {
245                 final UIColumn column = (UIColumn) child;
246 
247                 columns.add(column);
248             }
249         }
250 
251         return columns;
252     }
253 
254     protected String addColumnValues(final DataList dataList, final StringBuilder input) {
255         for (final UIComponent component : dataList.getChildren()) {
256             if (component instanceof Column) {
257                 final UIColumn column = (UIColumn) component;
258                 for (final UIComponent childComponent : column.getChildren()) {
259                     if (component.isRendered()) {
260                         final String value = exportValue(FacesContext.getCurrentInstance(), childComponent);
261 
262                         if (value != null) {
263                             input.append(value + "\n \n");
264                         }
265                     }
266                 }
267                 return input.toString();
268             }
269             else {
270                 if (component.isRendered()) {
271                     final String value = exportValue(FacesContext.getCurrentInstance(), component);
272 
273                     if (value != null) {
274                         input.append(value + "\n \n");
275                     }
276                 }
277                 return input.toString();
278             }
279         }
280         return null;
281     }
282 
283     protected int getColumnsCount(final DataTable table) {
284         int count = 0;
285 
286         for (final UIColumn col : table.getColumns()) {
287             if (col instanceof DynamicColumn) {
288                 ((DynamicColumn) col).applyStatelessModel();
289             }
290 
291             if (!col.isRendered() || !col.isExportable()) {
292                 continue;
293             }
294 
295             count++;
296         }
297 
298         return count;
299     }
300 
301     protected int getColumnsCount(final SubTable table) {
302         int count = 0;
303 
304         for (final UIColumn col : table.getColumns()) {
305             if (col instanceof DynamicColumn) {
306                 ((DynamicColumn) col).applyStatelessModel();
307             }
308 
309             if (!col.isRendered() || !col.isExportable()) {
310                 continue;
311             }
312 
313             count++;
314         }
315 
316         return count;
317     }
318 
319     public boolean hasHeaderColumn(final DataTable table) {
320         for (final UIColumn col : table.getColumns()) {
321             if (col instanceof DynamicColumn) {
322                 ((DynamicColumn) col).applyStatelessModel();
323             }
324             if (col.isRendered()
325                         && (col instanceof UIColumn || col instanceof DynamicColumn)
326                         && (col.getFacet("header") != null || col.getHeaderText() != null)) {
327                 return true;
328             }
329 
330         }
331 
332         return false;
333     }
334 
335     public boolean hasHeaderColumn(final SubTable table) {
336         for (final UIComponent child : table.getChildren()) {
337             if (child.isRendered() && child instanceof UIColumn) {
338                 final UIColumn column = (UIColumn) child;
339 
340                 if (column.getFacet("header") != null || column.getHeaderText() != null) {
341                     return true;
342                 }
343             }
344 
345         }
346 
347         return false;
348     }
349 
350     public boolean hasFooterColumn(final SubTable table) {
351         for (final UIComponent child : table.getChildren()) {
352             if (child.isRendered() && child instanceof UIColumn) {
353                 final UIColumn column = (UIColumn) child;
354 
355                 if (column.getFacet("footer") != null || column.getHeaderText() != null) {
356                     return true;
357                 }
358             }
359 
360         }
361 
362         return false;
363     }
364 
365     public void setSkipComponents(final String skipComponentsValue) {
366         skipComponents = skipComponentsValue;
367     }
368 
369 }