View Javadoc

1   /*
2    * Copyright 2004-2006 the Seasar Foundation and the Others.
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, 
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.tuigwaa.controller;
17  
18  import java.util.Calendar;
19  import java.util.Collections;
20  import java.util.Date;
21  import java.util.GregorianCalendar;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.Map;
25  
26  import org.apache.commons.lang.StringUtils;
27  import org.seasar.tuigwaa.database.CriteriaFunctionFactory;
28  import org.seasar.tuigwaa.database.function.criteria.CriteriaFunction;
29  import org.seasar.tuigwaa.database.function.criteria.DateFuncCriteriaFunction;
30  import org.seasar.tuigwaa.database.function.criteria.LikeCriteriaFunction;
31  import org.seasar.tuigwaa.database.function.criteria.SubcriteriaFunction;
32  import org.seasar.tuigwaa.model.core.TgwAttribute;
33  import org.seasar.tuigwaa.model.core.TgwEntity;
34  import org.seasar.tuigwaa.model.core.impl.BooleanAttribute;
35  import org.seasar.tuigwaa.model.core.impl.DateAttribute;
36  import org.seasar.tuigwaa.model.core.impl.DoubleAttribute;
37  import org.seasar.tuigwaa.model.core.impl.FileAttribute;
38  import org.seasar.tuigwaa.model.core.impl.FloatAttribute;
39  import org.seasar.tuigwaa.model.core.impl.IntegerAttribute;
40  import org.seasar.tuigwaa.model.core.impl.LinkAttribute;
41  import org.seasar.tuigwaa.model.core.impl.LongAttribute;
42  import org.seasar.tuigwaa.model.core.impl.SecurityAttribute;
43  import org.seasar.tuigwaa.model.core.impl.StringAttribute;
44  import org.seasar.tuigwaa.model.core.impl.TimestampAttribute;
45  import org.seasar.tuigwaa.system.Constants;
46  import org.seasar.tuigwaa.util.TgwResource;
47  import org.seasar.tuigwaa.util.ajax.AbstractRowSetForm;
48  import org.seasar.tuigwaa.view.AttributeFormGenerateVisitor;
49  
50  import com.isenshi.util.HtmlBuffer;
51  
52  public abstract class AbstractFieldFilterForm extends AbstractRowSetForm {
53  
54  	protected static final Map FIELD_FORM_MAP;
55  
56  	private TgwEntity entity;
57  
58  	private boolean disjunction = false;
59  
60  	private String name;
61  
62  	static {
63  		Map basics = new HashMap();
64  		basics.put(IntegerAttribute.class, IntegerFieldForm.class);
65  		basics.put(LongAttribute.class, LongFieldForm.class);
66  		basics.put(FloatAttribute.class, FloatFieldForm.class);
67  		basics.put(DoubleAttribute.class, DoubleFieldForm.class);
68  		basics.put(BooleanAttribute.class, BooleanFieldForm.class);
69  		basics.put(StringAttribute.class, StringFieldForm.class);
70  		basics.put(DateAttribute.class, DateFieldForm.class);
71  		basics.put(TimestampAttribute.class, TimestampForm.class);
72  		basics.put(SecurityAttribute.class, StringFieldForm.class);
73  		FIELD_FORM_MAP = Collections.unmodifiableMap(basics);
74  	}
75  
76  	// [Start] ----- Setter Getter Method -----
77  
78  	public void setEntity(TgwEntity entity) {
79  		this.entity = entity;
80  	}
81  
82  	public final TgwEntity getEntity() {
83  		return entity;
84  	}
85  
86  	public void setDisjunction(boolean disjunction) {
87  		this.disjunction = disjunction;
88  	}
89  
90  	public boolean isDisjunction() {
91  		return disjunction;
92  	}
93  
94  	public void setName(String name) {
95  		this.name = name;
96  	}
97  
98  	public String getName() {
99  		return name;
100 	}
101 
102 	// [End] ----- Setter Getter Method -----
103 
104 	protected final FieldForm createFieldForm(TgwAttribute field,
105 			String fieldName) {
106 		return createFieldForm(field, fieldName, true);
107 	}
108 
109 	protected final FieldForm createFieldForm(TgwAttribute field,
110 			String fieldName, boolean needValue) {
111 		Class clazz = (Class) FIELD_FORM_MAP.get(field.getClass());
112 		FieldForm form = null;
113 		try {
114 			form = (FieldForm) clazz.newInstance();
115 		} catch (InstantiationException e) {
116 			// Do Nothing
117 			e.printStackTrace();
118 		} catch (IllegalAccessException e) {
119 			// Do Nothing
120 			e.printStackTrace();
121 		}
122 		form.setFieldName(fieldName);
123 		form.setEntity(getEntity());
124 		form.setNeedValue(needValue);
125 		return form;
126 	}
127 
128 	protected final String getHtmlCell(int rowIndex, int columnIndex,
129 			String restriction) {
130 		FieldForm fieldForm = (FieldForm) getRow(rowIndex);
131 		if (fieldForm.isNeedValue()) {
132 			return fieldForm.updateValueHtml(rowIndex, restriction);
133 		} else {
134 			return fieldForm.createRemoveButton(rowIndex);
135 		}
136 	}
137 
138 	protected CriteriaFunction getFunction(String type, TgwEntity entity,
139 			String field) {
140 		return getFunction(type, entity, field, null);
141 	}
142 
143 	protected CriteriaFunction getFunction(String type, TgwEntity entity,
144 			String field, Object value) {
145 
146 		CriteriaFunction function = null;
147 
148 		int index = field.indexOf(".");
149 		if (index < 0) {
150 			String option = null;
151 			int optionIndex = type.indexOf("?");
152 			if (optionIndex > 0) {
153 				option = type.substring(optionIndex + 1, type.length());
154 				type = type.substring(0, optionIndex);
155 			}
156 			function = CriteriaFunctionFactory.getFunction(type);
157 			function.setField(field);
158 			function.setValue(value);
159 			function.setOption(option);
160 		} else {
161 			String thisField = field.substring(0, index);
162 			String nestedField = field.substring(index + 1, field.length());
163 			TgwEntity refEntity = ((LinkAttribute) entity.getField(thisField))
164 					.getRefEntity();
165 			CriteriaFunction sequentialFunction = getFunction(type, refEntity,
166 					nestedField, value);
167 			function = new SubcriteriaFunction(thisField, sequentialFunction);
168 		}
169 		return function;
170 	}
171 
172 	public static abstract class FieldForm {
173 
174 		private static final int FORM_FIELD = 0;
175 
176 		private static final int FORM_TYPE = 1;
177 
178 		private static final int FORM_VALUE = 2;
179 
180 		private static final int FORM_ACTION = 3;
181 
182 		private static final int LENGTH_FORM = 4;
183 
184 		protected static final String EQ = "eq";
185 
186 		protected static final String NE = "ne";
187 
188 		protected static final String LE = "le";
189 
190 		protected static final String LT = "lt";
191 
192 		protected static final String GE = "ge";
193 
194 		protected static final String GT = "gt";
195 
196 		protected static final String ISNULL = "isNull";
197 
198 		protected static final String ISNOTNULL = "isNotNull";
199 
200 		protected static final String BETWEEN = "between";
201 
202 		protected static final String DATEFUNC = "dateFunc";
203 
204 		protected static final String SECURITY = "security";
205 
206 		protected static final String LIKE_HEAD = "like?"
207 				+ LikeCriteriaFunction.TYPE_HEAD;
208 
209 		protected static final String LIKE_TAIL = "like?"
210 				+ LikeCriteriaFunction.TYPE_TAIL;
211 
212 		protected static final String LIKE_IN = "like?"
213 				+ LikeCriteriaFunction.TYPE_IN;
214 
215 		private boolean needValue = true; // default is true
216 
217 		private String type_;
218 
219 		private String fieldName_;
220 
221 		private Object value_;
222 
223 		private TgwEntity entity_;
224 
225 		private String displayName;
226 
227 		private AttributeFormGenerateVisitor visitor_ = AttributeFormGenerateVisitor.SEARCHFORM_INSTANCE;
228 
229 		public void setDisplayName(String displayName) {
230 			this.displayName = displayName;
231 		}
232 
233 		public String getDisplayName() {
234 			return displayName;
235 		}
236 
237 		public void setNeedValue(boolean needValue) {
238 			this.needValue = needValue;
239 		}
240 
241 		public void setEntity(TgwEntity entity) {
242 			this.entity_ = entity;
243 		}
244 
245 		public void setType(String type) {
246 			this.type_ = type;
247 		}
248 
249 		public String getType() {
250 			return this.type_;
251 		}
252 
253 		public void setFieldName(String fieldName) {
254 			this.fieldName_ = fieldName;
255 		}
256 
257 		public String getFieldName() {
258 			return this.fieldName_;
259 		}
260 
261 		public TgwAttribute getField() {
262 			return getEntity().getField(getFieldName());
263 		}
264 
265 		public boolean isNeedValue() {
266 			return needValue;
267 		}
268 
269 		public void setValue(Object value) {
270 			this.value_ = value;
271 		}
272 
273 		public Object getValue() {
274 			return value_;
275 		}
276 
277 		protected TgwEntity getEntity() {
278 			return entity_;
279 		}
280 
281 		public String[] getHtmlData(int index) {
282 			String fieldName = getFieldName();
283 			String[] data = null;
284 
285 			if (needValue) {
286 				data = new String[LENGTH_FORM];
287 				data[FORM_VALUE] = getValueHtml(index, fieldName);
288 				data[FORM_ACTION] = createRemoveButton(index);
289 			} else {
290 				data = new String[LENGTH_FORM - 1];
291 				data[FORM_ACTION - 1] = createRemoveButton(index);
292 			}
293 			data[FORM_TYPE] = getTypeHtml(index);
294 			data[FORM_FIELD] = getFieldHtml(index, fieldName);
295 			return data;
296 
297 		}
298 
299 		protected String createRemoveButton(int index) {
300 			return createRemoveButtonHtml(index, TgwResource
301 					.getMessage("button.remove"));
302 		}
303 
304 		private final String getFieldHtml(int index, String selectedFieldName) {
305 			HtmlBuffer buf = new HtmlBuffer();
306 
307 			buf.appendStartTag("select");
308 			buf.appendAttribute("name", getPrefix(index) + "fieldName");
309 			bindTypeEvent(buf);
310 
311 			Iterator itr = entity_.getAllFieldList().iterator();
312 
313 			while (itr.hasNext()) {
314 				TgwAttribute field = (TgwAttribute) itr.next();
315 				if (field instanceof FileAttribute) {
316 					continue;
317 				}
318 				buf.appendOption(field.getDisplayName(), field.getName(),
319 						selectedFieldName);
320 			}
321 
322 			buf.appendOption(getEntity().getPrimaryKeyDisplayName(),
323 					Constants.ENTITY_BUILTIN_ID, selectedFieldName);
324 			buf.endTag();
325 			return buf.toString();
326 		}
327 
328 		private final String getTypeHtml(int index) {
329 			HtmlBuffer buf = new HtmlBuffer();
330 			buf.appendStartTag("select");
331 			buf.appendAttribute("name", getPrefix(index) + "type");
332 			bindTypeEvent(buf, "onChangeRestriction(this);");
333 
334 			String[] pickTypes = getPickTypes();
335 
336 			for (int i = 0; i < pickTypes.length; i++) {
337 				String value = pickTypes[i];
338 
339 				String key = null;
340 				if (needValue) {
341 					key = "filter.label." + value;
342 				} else {
343 					if (value.equals("between") || value.equals("dateFunc")
344 							|| value.equals("security")) {
345 						continue;
346 					}
347 					key = "search.label." + value;
348 				}
349 
350 				String label = TgwResource.getMessage(key);
351 
352 				buf.appendOption(label, value, type_);
353 			}
354 			buf.endTag();
355 			return buf.toString();
356 		}
357 
358 		// this method is called at changing field name;
359 		protected String getValueHtml(int index, String fieldName) {
360 			// return createTextField(getPrefix(index) + "valueField");
361 			return (String) getField().accept(getVisitor(),
362 					getPrefix(index) + "valueField");
363 		}
364 
365 		// this method is called at changeing restriction;
366 		protected String updateValueHtml(int index, String restriction) {
367 			if (isNullablePickType(restriction)) {
368 				return "";
369 			}
370 			return getValueHtml(index, getFieldName());
371 		}
372 
373 		abstract String[] getPickTypes();
374 
375 		private AttributeFormGenerateVisitor getVisitor() {
376 			return visitor_;
377 		}
378 
379 		public void setVisitor(AttributeFormGenerateVisitor visitor) {
380 			this.visitor_ = visitor;
381 		}
382 
383 		protected boolean isNullablePickType(String restriction) {
384 			if (restriction == null)
385 				return false; // should throw Exception
386 			return ISNULL.equals(restriction) || ISNOTNULL.equals(restriction);
387 		}
388 
389 	}
390 
391 	public static class IntegerFieldForm extends FieldForm {
392 
393 		private static final String[] pickValues = { EQ, NE, LE, LT, GE, GT,
394 				ISNULL, ISNOTNULL };
395 
396 		public String[] getPickTypes() {
397 			return pickValues;
398 		}
399 
400 		public void setValueField(Integer value) {
401 			setValue(value);
402 		}
403 	}
404 
405 	public static class LongFieldForm extends FieldForm {
406 
407 		private static final String[] pickValues = { EQ, NE, LE, LT, GE, GT,
408 				ISNULL, ISNOTNULL };
409 
410 		public String[] getPickTypes() {
411 			return pickValues;
412 		}
413 
414 		public void setValueField(Long value) {
415 			setValue(value);
416 		}			
417 	}
418 
419 	public static class DoubleFieldForm extends FieldForm {
420 
421 		private static final String[] pickValues = { EQ, NE, LE, LT, GE, GT,
422 				ISNULL, ISNOTNULL };
423 
424 		public String[] getPickTypes() {
425 			return pickValues;
426 		}
427 
428 		public void setValueField(Double value) {
429 			setValue(value);
430 		}
431 	}
432 
433 	public static class FloatFieldForm extends FieldForm {
434 
435 		private static final String[] pickValues = { EQ, NE, LE, LT, GE, GT,
436 				ISNULL, ISNOTNULL };
437 
438 		public String[] getPickTypes() {
439 			return pickValues;
440 		}
441 
442 		public void setValueField(Float value) {
443 			setValue(value);
444 		}
445 	}
446 
447 	public static class StringFieldForm extends FieldForm {
448 
449 		private static final String[] pickTypes = { EQ, NE, LIKE_HEAD,
450 				LIKE_TAIL, LIKE_IN, SECURITY, ISNULL, ISNOTNULL };
451 
452 		public String[] getPickTypes() {
453 			String attrName = getFieldName();
454 			// TgwEntity entity = getEntity();
455 			if (attrName.indexOf('.') > 0) {
456 				String[] newpicktypes = new String[pickTypes.length + 1];
457 				for (int i = 0; i < pickTypes.length; i++) {
458 					newpicktypes[i] = pickTypes[i];
459 				}
460 				newpicktypes[newpicktypes.length - 1] = "eq?list";
461 				return newpicktypes;
462 			} else {
463 				return pickTypes;
464 			}
465 		}
466 
467 		public void setValueField(String value) {
468 			setValue(value);
469 		}
470 
471 		protected String updateValueHtml(int index, String restriction) {
472 			if (SECURITY.equals(restriction) || isNullablePickType(restriction)) {
473 				return "";
474 			} else {
475 				StringAttribute attr = (StringAttribute) getField();
476 				String html = (String) attr.accept(
477 						AttributeFormGenerateVisitor.DEFAULT_INSTANCE,
478 						getPrefix(index) + "valueField");
479 				// return super.updateValueHtml(index, restriction);
480 				return html;
481 			}
482 		}
483 	}
484 
485 	public static class BooleanFieldForm extends FieldForm {
486 
487 		private static final String[] pickTypes = { EQ, NE, ISNULL, ISNOTNULL };
488 
489 		public String[] getPickTypes() {
490 			return pickTypes;
491 		}
492 
493 		public void setValueField(Boolean value) {
494 			setValue(value);
495 		}
496 
497 		public Object getValue() {
498 			if (ISNULL.equals(getType())) {
499 				return null;
500 			}
501 			return super.getValue();
502 		}
503 
504 		// override
505 		protected String getValueHtml(int index, String fieldName) {
506 			HtmlBuffer buf = new HtmlBuffer();
507 			buf.appendStartTag("select");
508 			buf.appendAttribute("name", getPrefix(index) + "valueField");
509 
510 			BooleanAttribute bField = (BooleanAttribute) getEntity().getField(
511 					fieldName);
512 
513 			String value = null;
514 			if (getValue() != null) {
515 				value = getValue().toString();
516 			}
517 
518 			buf.appendOption(bField.getTrueStr(), "true", value);
519 			buf.appendOption(bField.getFalseStr(), "false", value);
520 
521 			buf.endTag();
522 
523 			return buf.toString();
524 		}
525 	}
526 
527 	public static class TimestampForm extends DateFieldForm {
528 		private static final String[] pickTypes = { LE, GE, BETWEEN, DATEFUNC };
529 
530 		public String[] getPickTypes() {
531 			return pickTypes;
532 		}
533 	}
534 
535 	public static class DateFieldForm extends FieldForm {
536 
537 		private static final String[] pickTypes = { EQ, LE, GE, NE, BETWEEN,
538 				DATEFUNC, ISNULL, ISNOTNULL };
539 
540 		public String[] getPickTypes() {
541 			return pickTypes;
542 		}
543 
544 		private int year_;
545 
546 		private int month_;
547 
548 		private int date_;
549 
550 		private int year2;
551 
552 		private int month2;
553 
554 		private int date2;
555 
556 		private String selectType;
557 
558 		public String getSelectType() {
559 			return selectType;
560 		}
561 
562 		public void setSelectType(String selectType) {
563 			this.selectType = selectType;
564 		}
565 
566 		public int getYear() {
567 			return year_;
568 		}
569 
570 		public void setYear(int year) {
571 			this.year_ = year;
572 		}
573 
574 		public int getMonth() {
575 			return month_;
576 		}
577 
578 		public void setMonth(int month) {
579 			this.month_ = month;
580 		}
581 
582 		public int getDate() {
583 			return date_;
584 		}
585 
586 		public void setDate(int date) {
587 			this.date_ = date;
588 		}
589 
590 		public int getDate2() {
591 			return date2;
592 		}
593 
594 		public void setDate2(int date2) {
595 			this.date2 = date2;
596 		}
597 
598 		public int getMonth2() {
599 			return month2;
600 		}
601 
602 		public void setMonth2(int month2) {
603 			this.month2 = month2;
604 		}
605 
606 		public int getYear2() {
607 			return year2;
608 		}
609 
610 		public void setYear2(int year2) {
611 			this.year2 = year2;
612 		}
613 
614 		public Object getValue() {
615 			String type = getType();
616 			if (DATEFUNC.equals(type)) {
617 				return getSelectType();
618 			} else if (BETWEEN.equals(type)) {
619 				Date[] dates = new Date[2];
620 				dates[0] = getDate(getYear(), getMonth(), getDate());
621 				dates[1] = getDate(getYear2(), getMonth2(), getDate2());
622 				return dates;
623 			} else {
624 				return getDate(getYear(), getMonth(), getDate());
625 			}
626 		}
627 
628 		private Object getValueFromValueObject() {
629 			String type = getType();
630 			if (DATEFUNC.equals(type)) {
631 				return getSelectType();
632 			} else {
633 				return super.getValue();
634 			}
635 		}
636 
637 		private Date getDate(int year, int month, int date) {
638 			Calendar cal = new GregorianCalendar(year, month - 1, date);
639 			return cal.getTime();
640 		}
641 
642 		protected String getValueHtml(int index, String fieldName) {
643 			if (StringUtils.isNotEmpty(getType())) {
644 				return updateValueHtml(index, getType());
645 			}
646 			return updateValueHtml(index, getPickTypes()[0]);
647 		}
648 
649 		public void setValue(Object value) {
650 			if (DATEFUNC.equals(getType())) {
651 				setSelectType((String) value);
652 			}
653 			super.setValue(value);
654 		}
655 
656 		protected String updateValueHtml(int index, String restriction) {
657 			if (DATEFUNC.equals(restriction)) {
658 				return getSelectTypeField(index);
659 			} else if (BETWEEN.equals(restriction)) {
660 				return getValueHtml(index, false) + "-"
661 						+ getValueHtml(index, true);
662 			} else if (isNullablePickType(restriction)) {
663 				return "";
664 			} else {
665 				return getValueHtml(index);
666 			}
667 		}
668 
669 		private String getSelectTypeField(int index) {
670 			HtmlBuffer buf = new HtmlBuffer();
671 
672 			buf.appendStartTag("select");
673 			buf.appendAttribute("name", getPrefix(index) + "selectType");
674 
675 			for (int i = 0; i < DateFuncCriteriaFunction.DATE_TYPE.length; i++) {
676 				String type = DateFuncCriteriaFunction.DATE_TYPE[i];
677 				String label = TgwResource.getMessage("datefield." + type);
678 				buf.appendOption(label, type, getSelectType());
679 			}
680 
681 			buf.endTag();
682 			return buf.toString();
683 		}
684 
685 		protected String getValueHtml(int index) {
686 			return getValueHtml(index, false);
687 		}
688 
689 		protected String getValueHtml(int index, boolean isSuffix) {
690 			String suffix = "";
691 			if (isSuffix) {
692 				suffix = "2";
693 			}
694 
695 			int startYear = Calendar.getInstance().get(Calendar.YEAR) - 10;
696 			int endYear = Calendar.getInstance().get(Calendar.YEAR) + 10;
697 
698 			if (getField() instanceof DateAttribute) {
699 				DateAttribute dField = (DateAttribute) getField();
700 				startYear = dField.getStartValue();
701 				endYear = dField.getEndValue();
702 			}
703 
704 			String yearLabel = getPrefix(index) + "year" + suffix;
705 			String monthLabel = getPrefix(index) + "month" + suffix;
706 			String dateLabel = getPrefix(index) + "date" + suffix;
707 
708 			String onchange = null;
709 
710 			HtmlBuffer buf = new HtmlBuffer();
711 
712 			String values[] = getDateValues(suffix);
713 
714 			buf.appendSelect(yearLabel, startYear, endYear, values[0],
715 					onchange, false);
716 			buf.appendSelect(monthLabel, 1, 12, values[1], onchange, false);
717 			buf.appendSelect(dateLabel, 1, 31, values[2], onchange, false);
718 
719 			return buf.toString();
720 		}
721 
722 		private String[] getDateValues(String suffix) {
723 			String[] str = new String[3];
724 			Date d = null;
725 			if (getValueFromValueObject() == null) {
726 				return str;
727 			} else if (getValueFromValueObject() instanceof Date) {
728 				d = (Date) getValueFromValueObject();
729 			} else if (BETWEEN.equals(getType())) {
730 				Date[] date = (Date[]) getValueFromValueObject();
731 				if ("".equals(suffix)) {
732 					d = date[0];
733 				} else if ("2".equals(suffix)) {
734 					d = date[1];
735 				}
736 			}
737 
738 			Calendar cal = GregorianCalendar.getInstance();
739 			cal.setTime(d);
740 			str[0] = String.valueOf(cal.get(Calendar.YEAR));
741 			str[1] = String.valueOf(cal.get(Calendar.MONTH) + 1);
742 			str[2] = String.valueOf(cal.get(Calendar.DAY_OF_MONTH));
743 			return str;
744 		}
745 	}
746 }