PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/org/apache/struts2/jquery/components/Grid.java

http://struts2-jquery-plugin.googlecode.com/
Java | 509 lines | 434 code | 74 blank | 1 comment | 106 complexity | 646162a29a8529f276367855da4b2365 MD5 | raw file
  1. package org.apache.struts2.jquery.components;
  2. import java.lang.reflect.Array;
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import java.util.HashMap;
  6. import java.util.Iterator;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.Map.Entry;
  10. import javax.servlet.http.HttpServletRequest;
  11. import javax.servlet.http.HttpServletResponse;
  12. import org.apache.commons.lang.xwork.StringUtils;
  13. import org.apache.struts2.util.MakeIterator;
  14. import org.apache.struts2.views.annotations.StrutsTag;
  15. import org.apache.struts2.views.annotations.StrutsTagAttribute;
  16. import com.opensymphony.xwork2.util.ValueStack;
  17. @StrutsTag(name="grid", tldTagClass="org.apache.struts2.jquery.views.jsp.ui.GridTag",
  18. description="Render a dynamic grid providing content from list or remote call via AJAX",
  19. allowDynamicAttributes=true)
  20. public class Grid extends AbstractContainer {
  21. public static final String TEMPLATE = "grid";
  22. public static final String TEMPLATE_CLOSE = "grid-close";
  23. protected Object data; //An object with the grid data
  24. protected String options; //A catch-all for the user to specify custom jQGrid options above the ones specific provided for as attributes. options provided here will override those set as attributes.
  25. protected Object columnNames; //A list of column names. The list should be the same length as the number of columns in the data
  26. protected Object columnWidths; //A List or map of column widths. If a collection is provided, the order of the collection is assumed to be the order of the columns. If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)
  27. protected Object columnSortables; //A list or map of booleans indicating whether a column is sortable or not. If a collection is provided, the order of the collection is assumed to be the order of the columns. If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)
  28. protected Object columnEditables; //A list or map of booleans indicating whether a column is editable or not. If a collection is provided, the order of the collection is assumed to be the order of the columns. If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)
  29. protected Object columnResizables; //A list or map of booleans indicating whether a column is resizable or not. If a collection is provided, the order of the collection is assumed to be the order of the columns. If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)
  30. protected Object columnAlignments; //A list or map of Strings indicating the alignment of a column. Valid string value are 'right','left','center', or null. If a collection is provided, the order of the collection is assumed to be the order of the columns. If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)
  31. protected Object columnSortTypes; //A list or map of sort types for each column. The sort types are int/integer/float/number/currency/date/text (defaults to 'text'). If a collection is provided, the order of the collection is assumed to be the order of the columns. If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)
  32. protected Object columnLabels; //A list or map of labels for the columns. If a collection is provided, the order of the collection is assumed to be the order of the columns. If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)
  33. protected Object columnDateFormats; //A list or map of the date formats for each column. The sort types are int/integer/float/number/currency/date/text (defaults to 'text'). If a collection is provided, the order of the collection is assumed to be the order of the columns. If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)
  34. protected String sortColumn; //The name or index of the column to be sorted first
  35. protected String sortAscending; //A boolean indicating whether to sort the initial column in ascending order (true=ascending, false=descending). Only used if sortColumn is set.
  36. protected String pager; //A boolean indicating whether the 'pager' control which provides paging navigation should be shown
  37. protected String rowsPerPage; //An integer with the number of rows that should be displayed on a page
  38. protected Object rowsPerPageOptions; //A list or comma delimited string of integers of the choices for rows-per-page'
  39. protected String showTotal; //A boolean indicating whether or not to display the number of total records from the query in the pager bar.
  40. protected String caption; //The caption for the grid
  41. protected String height; //The height of the grid. Can be an integer value (pixels) or a percentage string (like '40%');
  42. protected String width; //The width of the grid. Can be an integer value (pixels) or a percentage string (like '40%');
  43. protected List<Column> columns;
  44. public Grid(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
  45. super(stack, request, response);
  46. }
  47. @Override
  48. public void evaluateExtraParams() {
  49. super.evaluateExtraParams();
  50. if (options != null){
  51. addParameter("options", findString(options));
  52. }
  53. if (pager != null){
  54. addParameter("pager", findValue(pager, Boolean.class));
  55. }
  56. if (sortAscending != null){
  57. addParameter("sortAscending", findValue(sortAscending, Boolean.class));
  58. }
  59. if (sortColumn != null){
  60. addParameter("sortColumn", findString(sortColumn));
  61. }
  62. if (rowsPerPage != null){
  63. addParameter("rowsPerPage", findValue(rowsPerPage, Integer.class));
  64. }
  65. if (height != null){
  66. addParameter("height", findString(height));
  67. }
  68. if (width != null){
  69. addParameter("width", findString(width));
  70. }
  71. addListParameter(rowsPerPageOptions,"rowsPerPageOptions");
  72. if (showTotal != null){
  73. addParameter("showTotal", findValue(showTotal, Boolean.class));
  74. }
  75. if (caption != null){
  76. addParameter("caption", findString(caption));
  77. }
  78. if (data == null) {
  79. data = parameters.get("data");
  80. }
  81. Object value = null;
  82. if (data instanceof String) {
  83. value = findValue((String) data);
  84. } else if (data instanceof Collection<?>) {
  85. value = data;
  86. }
  87. Integer columnCount = null;
  88. Integer dataLength = null;
  89. if (value instanceof Collection<?>) {
  90. List<?> grid = new ArrayList<Object>((Collection<?>)value);
  91. dataLength = grid.size();
  92. if(!grid.isEmpty()) {
  93. Object row = grid.get(0);
  94. if(row instanceof Collection<?>) {
  95. columnCount = ((Collection<?>)row).size();
  96. value = grid;
  97. } else if(row.getClass().isArray()) {
  98. columnCount = ((Object[])row).length;
  99. //TODO: convert row arrays to collections
  100. } else {
  101. value = null;
  102. }
  103. } else {
  104. value = null;
  105. }
  106. } else if (value != null && value.getClass().isArray()) {
  107. Object[] array = (Object[])value;
  108. dataLength = array.length;
  109. if(array.length > 0 && array[0].getClass().isArray()) {
  110. ArrayList<ArrayList<Object>> grid = new ArrayList<ArrayList<Object>>(Array.getLength(value));
  111. ArrayList<Object> row;
  112. Object rowObject = array[0];
  113. if(rowObject.getClass().isArray()) {
  114. columnCount = ((Object[])rowObject).length;
  115. for (int i = 0; i < array.length; i++) {
  116. Object[] rowArray = (Object[])array[i];
  117. row = new ArrayList<Object>();
  118. for(int j = 0; j < rowArray.length; ++j) {
  119. row.add(rowArray[j]);
  120. }
  121. grid.add(row);
  122. }
  123. } else if(rowObject instanceof Collection<?>){
  124. columnCount = ((Collection<?>)rowObject).size();
  125. for (int i = 0; i < array.length; i++) {
  126. grid.add(new ArrayList<Object>((Collection<?>)array[i]));
  127. }
  128. }
  129. value = grid;
  130. } else {
  131. value = null;
  132. }
  133. } else {
  134. value = null;
  135. dataLength = 0;
  136. }
  137. addParameter("data", MakeIterator.convert(value));
  138. addParameter("dataLength", dataLength);
  139. columns = new ArrayList<Column>();
  140. List<?> columnNameList = makeList(columnNames);
  141. Map<Integer,?> columnWidthsMap = makeMap(columnWidths, columnNameList);
  142. Map<Integer,?> columnSortablesMap = makeMap(columnSortables, columnNameList);
  143. Map<Integer,?> columnSortTypesMap = makeMap(columnSortTypes, columnNameList);
  144. Map<Integer,?> columnEditablesMap = makeMap(columnEditables, columnNameList);
  145. Map<Integer,?> columnResizablesMap = makeMap(columnResizables, columnNameList);
  146. Map<Integer,?> columnAlignmentsMap = makeMap(columnAlignments, columnNameList);
  147. Map<Integer,?> columnDateFormatsMap = makeMap(columnDateFormats, columnNameList);
  148. Map<Integer,?> columnLabelsMap = makeMap(columnLabels, columnNameList);
  149. columnCount = columnCount != null ? columnCount : (columnNameList != null ? columnNameList.size() : null);
  150. if(columnCount != null) {
  151. Column column;
  152. for (int i = 0; i < columnCount; i++) {
  153. column = new Column();
  154. column.name = columnNameList.size() > i ? columnNameList.get(i).toString() : null;
  155. column.width = columnWidthsMap.size() > i ? Integer.valueOf(columnWidthsMap.get(i).toString()) : null;
  156. column.sortable = columnSortablesMap.size() > i ? Boolean.valueOf(columnSortablesMap.get(i).toString()) : null;
  157. column.editable = columnEditablesMap.size() > i ? Boolean.valueOf(columnEditablesMap.get(i).toString()) : null;
  158. column.resizable = columnResizablesMap.size() > i ? Boolean.valueOf(columnResizablesMap.get(i).toString()) : null;
  159. column.alignment = columnAlignmentsMap.size() > i ? columnAlignmentsMap.get(i).toString() : null;
  160. column.alignment = columnAlignmentsMap.size() > i ? columnAlignmentsMap.get(i).toString() : null;
  161. column.label = columnLabelsMap.size() > i ? columnLabelsMap.get(i).toString() : null;
  162. column.sortType = columnSortTypesMap.size() > i ? columnSortTypesMap.get(i).toString() : null;
  163. column.dateFormat = columnDateFormatsMap.size() > i ? columnDateFormatsMap.get(i).toString() : null;
  164. columns.add(column);
  165. }
  166. }
  167. addParameter("columns", columns);
  168. }
  169. @SuppressWarnings("unchecked")
  170. private List<?> makeList(Object parameter) {
  171. Object value = null;
  172. if (parameter != null){
  173. if(parameter instanceof String) {
  174. if(((String)parameter).contains(",")) {
  175. value = ((String)parameter).split(",");
  176. } else {
  177. value = findValue(parameter.toString());
  178. }
  179. if(value != null) {
  180. parameter = value;
  181. }else {
  182. parameter = new String[]{(String)parameter};
  183. }
  184. }
  185. if (parameter instanceof Collection<?>) {
  186. value = new ArrayList<Object>((Collection<?>)parameter);
  187. } else if(parameter.getClass().isArray()) {
  188. Object[] array = (Object[])parameter;
  189. value = new ArrayList<Object>(array.length);
  190. for (int i = 0; i < array.length; i++) {
  191. ((ArrayList<Object>)value).add(array[i]);
  192. }
  193. } else if(parameter instanceof Iterable<?>) {
  194. Iterable<?> iterable = (Iterable<?>)parameter;
  195. value = new ArrayList<Object>();
  196. for (Object object : iterable) {
  197. ((ArrayList<Object>)value).add(object);
  198. }
  199. value = parameter.toString();
  200. } else if(parameter instanceof Iterator<?>) {
  201. value = new ArrayList<Object>();
  202. for (Iterator<?> iterator = (Iterator<?>)parameter; iterator.hasNext();) {
  203. ((ArrayList<Object>)value).add(iterator.next());
  204. }
  205. }
  206. }
  207. return value == null ? new ArrayList<Object>() : (List<?>)value;
  208. }
  209. @SuppressWarnings("unchecked")
  210. private Map<Integer,?> makeMap(Object parameter, List<?> keyNames) {
  211. Object value = null;
  212. if (parameter != null){
  213. if(parameter instanceof String) {
  214. if(((String)parameter).contains(",")) {
  215. value = ((String)parameter).split(",");
  216. } else {
  217. value = findValue(parameter.toString());
  218. }
  219. if(value != null) {
  220. parameter = value;
  221. } else {
  222. parameter = new String[]{(String)parameter};
  223. }
  224. }
  225. if (parameter instanceof Collection<?>) {
  226. value = new HashMap<Integer,Object>();
  227. int i = 0;
  228. for (Object object : (Collection<?>)parameter) {
  229. ((HashMap<Integer,Object>)value).put(i, object);
  230. i++;
  231. }
  232. } else if(parameter.getClass().isArray()) {
  233. Object[] array = (Object[])parameter;
  234. value = new HashMap<Integer,Object>();
  235. for (int i = 0; i < array.length; i++) {
  236. ((HashMap<Integer,Object>)value).put(i, array[i]);
  237. }
  238. } else if(parameter instanceof Iterable<?>) {
  239. Iterable<?> iterable = (Iterable<?>)parameter;
  240. value = new HashMap<Integer,Object>();
  241. int i = 0;
  242. for (Object object : iterable) {
  243. ((HashMap<Integer,Object>)value).put(i, object);
  244. i++;
  245. }
  246. value = parameter.toString();
  247. } else if(parameter instanceof Iterator<?>) {
  248. value = new HashMap<Integer,Object>();
  249. int i = 0;
  250. for (Iterator<?> iterator = (Iterator<?>)parameter; iterator.hasNext();) {
  251. ((HashMap<Integer,Object>)value).put(i, iterator.next());
  252. }
  253. } else if(parameter instanceof Map<?,?>) {
  254. Map<?,?> map = (Map<?,?>)parameter;
  255. if(!map.isEmpty()) {
  256. Object key = map.keySet().iterator().next();
  257. if(key instanceof String) {
  258. if(keyNames != null) {
  259. for (Entry<?, ?> entry : map.entrySet()) {
  260. Integer index = keyNames.indexOf(key);
  261. if(index >= 0) {
  262. ((HashMap<Integer,Object>)value).put(index, entry.getValue());
  263. }
  264. }
  265. }
  266. } else if(key instanceof Integer) {
  267. value = map;
  268. }
  269. }
  270. }
  271. }
  272. return value == null ? new HashMap<Integer, Object>() : (Map<Integer,?>)value;
  273. }
  274. private void addListParameter(Object parameter, String name) {
  275. Object value = null;
  276. if (parameter != null){
  277. if(parameter instanceof String && !((String)parameter).contains(",")) {
  278. value = findValue(parameter.toString());
  279. if(value != null) {
  280. parameter = value;
  281. } else {
  282. parameter = new String[]{(String)parameter};
  283. }
  284. }
  285. if (parameter instanceof Collection<?>) {
  286. value = StringUtils.join((Collection<?>)parameter, ",");
  287. } else {
  288. value = parameter.toString();
  289. }
  290. addParameter(name, value);
  291. }
  292. }
  293. public class Column {
  294. private String name;
  295. private String index;
  296. private String alignment;
  297. private Integer width;
  298. private String label;
  299. private Boolean resizable = true;
  300. private Boolean editable = false;
  301. private Boolean sortable = false;
  302. private String sortType;
  303. private String dateFormat;
  304. public String getName() {
  305. return name;
  306. }
  307. public String getIndex() {
  308. return index;
  309. }
  310. public String getAlignment() {
  311. return alignment;
  312. }
  313. public Integer getWidth() {
  314. return width;
  315. }
  316. public String getLabel() {
  317. return label;
  318. }
  319. public Boolean getResizable() {
  320. return resizable;
  321. }
  322. public Boolean getEditable() {
  323. return editable;
  324. }
  325. public Boolean getSortable() {
  326. return sortable;
  327. }
  328. public String getSortType() {
  329. return sortType;
  330. }
  331. public String getDateFormat() {
  332. return dateFormat;
  333. }
  334. }
  335. @Override
  336. public String getDefaultOpenTemplate() {
  337. return TEMPLATE;
  338. }
  339. @Override
  340. protected String getDefaultTemplate() {
  341. return TEMPLATE_CLOSE;
  342. }
  343. @StrutsTagAttribute(description="Iterable source to populate table from. Typically the data will be a collection of collections where each contained collection is " +
  344. "a row in the table. The natural sorting order of the iterator obtained from the collections will be used to sort the rows and" +
  345. "the columns. This should not be used together with the 'src' attribute", required=false)
  346. public void setData(Object data) {
  347. this.data = data;
  348. }
  349. @StrutsTagAttribute(description="A catch-all for the user to specify custom jqGrid options above the ones specific provided for as attributes. options provided here will override those set as attributes.", required=false)
  350. public void setOptions(String options) {
  351. this.options = options;
  352. }
  353. @StrutsTagAttribute(description="A boolean indicating whether the 'pager' control which provides paging navigation should be shown", type="Boolean", defaultValue="false", required=false)
  354. public void setPager(String pager) {
  355. this.pager = pager;
  356. }
  357. @StrutsTagAttribute(description="A list or map or comma delimited string of Strings indicating the alignment of a column. Valid string value are 'right','left','center', or null. If a collection is provided, the order of the collection is assumed to be the order of the columns. " +
  358. "If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)", required=false)
  359. public void setColumnAlignments(Object columnAlignments) {
  360. this.columnAlignments = columnAlignments;
  361. }
  362. @StrutsTagAttribute(description="A list or map or comma delimited string of booleans indicating whether a column is editable or not. If a collection is provided, the order of the collection is assumed to be the order of the columns. " +
  363. "If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)", required=false)
  364. public void setColumnEditables(Object columnEditables) {
  365. this.columnEditables = columnEditables;
  366. }
  367. @StrutsTagAttribute(description="A list or comma delimited string of column names. The list should be the same length as the number of columns in the data", required=false)
  368. public void setColumnNames(Object columnNames) {
  369. this.columnNames = columnNames;
  370. }
  371. @StrutsTagAttribute(description="A list or map or comma delimited string of labels for the columns. If a collection is provided, the order of the collection is assumed to be the order of the columns. " +
  372. "If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)", required=false)
  373. public void setColumnLabels(Object columnLabels) {
  374. this.columnLabels = columnLabels;
  375. }
  376. @StrutsTagAttribute(description="A list or map or comma delimited string of booleans indicating whether a column is resizable or not. If a collection is provided, the order of the collection is assumed to be the order of the columns." +
  377. "If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)", required=false)
  378. public void setColumnResizables(Object columnResizables) {
  379. this.columnResizables = columnResizables;
  380. }
  381. @StrutsTagAttribute(description="A list or map or comma delimited string of booleans indicating whether a column is sortable or not. If a collection is provided, the order of the collection is assumed to be the order of the columns. " +
  382. "If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)", required=false)
  383. public void setColumnSortables(Object columnSortables) {
  384. this.columnSortables = columnSortables;
  385. }
  386. @StrutsTagAttribute(description="A list or map of sort types for each column. The sort types are int/integer/float/number/currency/date/text " +
  387. "(defaults to 'text'). If a collection is provided, the order of the collection is assumed to be the order of the columns. " +
  388. "If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)", required=false)
  389. public void setColumnSortTypes(Object columnSortTypes) {
  390. this.columnSortTypes = columnSortTypes;
  391. }
  392. @StrutsTagAttribute(description="A list or map of the date formats for each column. The sort types are int/integer/float/number/currency/date/text " +
  393. "(defaults to 'text'). If a collection is provided, the order of the collection is assumed to be the order of the columns. " +
  394. "If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)", required=false)
  395. public void setColumnDateFormats(Object columnDateFormats) {
  396. this.columnDateFormats = columnDateFormats;
  397. }
  398. @StrutsTagAttribute(description="A list or map or comma delimited string of column widths. If a collection is provided, the order of the collection is assumed to be the order of the columns. " +
  399. "If a map is provided, the key may be the column index (integer) or the column name (only if columnNames list is provided)", required=false)
  400. public void setColumnWidths(Object columnWidths) {
  401. this.columnWidths = columnWidths;
  402. }
  403. @StrutsTagAttribute(description="The name or index of the column to be sorted first when the grid is poulated remotely (using 'src')", required=false)
  404. public void setSortColumn(String sortColumn) {
  405. this.sortColumn = sortColumn;
  406. }
  407. @StrutsTagAttribute(description="A boolean indicating whether to sort the initial column in ascending order (true=ascending, false=descending). Only used if sortColumn is set and the grid is poulated remotely (using 'src')", type="Boolean", defaultValue="false", required=false)
  408. public void setSortAscending(String sortAscending) {
  409. this.sortAscending = sortAscending;
  410. }
  411. @StrutsTagAttribute(description="An integer with the number of rows that should be displayed on a page", type="Integer", required=false)
  412. public void setRowsPerPage(String rowsPerPage) {
  413. this.rowsPerPage = rowsPerPage;
  414. }
  415. @StrutsTagAttribute(description="A list or comma delimited string of integers of the choices for rows-per-page", required=false)
  416. public void setRowsPerPageOptions(Object rowsPerPageOptions) {
  417. this.rowsPerPageOptions = rowsPerPageOptions;
  418. }
  419. @StrutsTagAttribute(description="A boolean indicating whether or not to display the number of total records from the query in the pager bar.", type="Boolean", defaultValue="false", required=false)
  420. public void setShowTotal(String showTotal) {
  421. this.showTotal = showTotal;
  422. }
  423. @StrutsTagAttribute(name="caption", description="The caption for the grid",required=false)
  424. public void setCaption(String caption) {
  425. this.caption = caption;
  426. }
  427. @StrutsTagAttribute(name="height", description="The height of the grid. Can be an integer value (pixels) or a percentage string (like '40%')",required=false)
  428. public void setHeight(String height) {
  429. this.height = height;
  430. }
  431. @StrutsTagAttribute(name="width", description="The width of the grid. Can be an integer value (pixels) or a percentage string (like '40%');",required=false)
  432. public void setWidth(String width) {
  433. this.width = width;
  434. }
  435. }