1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.tuigwaa.view;
17
18 import java.util.Calendar;
19 import java.util.Date;
20 import java.util.Iterator;
21 import java.util.LinkedHashMap;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.apache.struts.util.ResponseUtils;
26 import org.seasar.tuigwaa.controller.config.ValidatorUtils;
27 import org.seasar.tuigwaa.model.common.EntityUtils;
28 import org.seasar.tuigwaa.model.common.TgwAttributeVisitor;
29 import org.seasar.tuigwaa.model.core.TgwAttribute;
30 import org.seasar.tuigwaa.model.core.TgwEntity;
31 import org.seasar.tuigwaa.model.core.impl.BooleanAttribute;
32 import org.seasar.tuigwaa.model.core.impl.DateAttribute;
33 import org.seasar.tuigwaa.model.core.impl.DoubleAttribute;
34 import org.seasar.tuigwaa.model.core.impl.FileAttribute;
35 import org.seasar.tuigwaa.model.core.impl.FkAttribute;
36 import org.seasar.tuigwaa.model.core.impl.FloatAttribute;
37 import org.seasar.tuigwaa.model.core.impl.IntegerAttribute;
38 import org.seasar.tuigwaa.model.core.impl.LongAttribute;
39 import org.seasar.tuigwaa.model.core.impl.SecurityAttribute;
40 import org.seasar.tuigwaa.model.core.impl.SelfAttribute;
41 import org.seasar.tuigwaa.model.core.impl.SetAttribute;
42 import org.seasar.tuigwaa.model.core.impl.StringAttribute;
43 import org.seasar.tuigwaa.model.core.impl.TimestampAttribute;
44 import org.seasar.tuigwaa.system.Constants;
45 import org.seasar.tuigwaa.util.TgwContext;
46 import org.seasar.tuigwaa.util.TgwNameUtils;
47 import org.seasar.tuigwaa.util.TgwResource;
48 import org.seasar.tuigwaa.util.functor.FileDownloadFunction;
49 import org.seasar.tuigwaa.view.wiki.DefaultDataViewVisitor;
50
51 import com.isenshi.util.CharUtil;
52 import com.isenshi.util.HtmlBuffer;
53 import com.isenshi.util.SimpleFile;
54 import com.isenshi.util.functor.BinaryFunction;
55
56 public class AttributeFormGenerateVisitor implements TgwAttributeVisitor {
57
58 private static final int DEFAULT_TEXTAREA_ROWS = 10;
59
60 private static final int DEFAULT_TEXTAREA_COLS = 40;
61
62 protected static final String NOT_EDITABLE = "msg.field.noteditable";
63
64 private Object valueObject;
65
66 private Map bindingFkObjMap;
67
68 private boolean searchFormFlag;
69
70 private boolean tableFormFlag;
71
72 private boolean macroFlag = false;
73
74 public static final AttributeFormGenerateVisitor DEFAULT_INSTANCE;
75
76 public static final AttributeFormGenerateVisitor SEARCHFORM_INSTANCE;
77
78 public static final AttributeFormGenerateVisitor MACRO_INSTANCE;
79
80 static {
81 DEFAULT_INSTANCE = new AttributeFormGenerateVisitor();
82
83 SEARCHFORM_INSTANCE = new AttributeFormGenerateVisitor();
84 SEARCHFORM_INSTANCE.searchFormFlag = true;
85
86 MACRO_INSTANCE = new AttributeFormGenerateVisitor();
87 MACRO_INSTANCE.macroFlag = true;
88 }
89
90 private AttributeFormGenerateVisitor() {
91 }
92
93 private AttributeFormGenerateVisitor(Object valueObj, Map bindingFkObjMap) {
94 this.valueObject = valueObj;
95 this.bindingFkObjMap = bindingFkObjMap;
96 }
97
98
99
100 public static AttributeFormGenerateVisitor create(Object valueObj,
101 Map bindingFkObjMap) {
102 return new AttributeFormGenerateVisitor(valueObj, bindingFkObjMap);
103 }
104
105 public static AttributeFormGenerateVisitor createTableForm(Object valueObj) {
106 AttributeFormGenerateVisitor visitor = new AttributeFormGenerateVisitor(
107 valueObj, null);
108 visitor.tableFormFlag = true;
109 return visitor;
110 }
111
112 public static AttributeFormGenerateVisitor createSearchVisitor(
113 Object valueObj) {
114 AttributeFormGenerateVisitor visitor = new AttributeFormGenerateVisitor();
115 visitor.searchFormFlag = true;
116 visitor.valueObject = valueObj;
117 return visitor;
118 }
119
120
121
122
123
124 public Object visit(StringAttribute attr, Object data) {
125 String elemName = (String) data;
126 if ("restriction".equals(attr.getOption())) {
127 return renderStringArray(attr, elemName);
128 } else {
129 return renderStringTextField(attr, elemName);
130 }
131 }
132
133 public Object visit(LongAttribute attr, Object data) {
134 return renderTextField(attr, (String) data);
135 }
136
137 public Object visit(IntegerAttribute attr, Object data) {
138 String elemName = (String) data;
139 if ("restriction".equals(attr.getOption())) {
140 return renderIntegerArray(attr, elemName);
141 } else {
142 return renderTextField(attr, elemName);
143 }
144 }
145
146 public Object visit(FloatAttribute field, Object data) {
147 String elemName = (String) data;
148 return renderTextField(field, elemName);
149 }
150
151 public Object visit(BooleanAttribute attr, Object data) {
152 String elemName = (String) data;
153 Boolean bool = (Boolean) getAttributeValue(attr, elemName);
154
155 boolean trueFlag = false;
156 boolean falseFlag = false;
157 if (bool != null) {
158 boolean booleanValue = bool.booleanValue();
159 trueFlag = booleanValue;
160 falseFlag = !booleanValue;
161 } else if (isRequired(attr)) {
162 trueFlag = true;
163 }
164
165 HtmlBuffer buf = new HtmlBuffer();
166 if (StringAttribute.FORM_CHECKBOX.equals(attr.getFormType())) {
167 buf.appendCheckBox(elemName, trueFlag);
168 } else if (!tableFormFlag) {
169
170 buf.appendRadio(elemName, "true", trueFlag);
171 buf.appendBody(attr.getTrueStr());
172 buf.appendRadio(elemName, "false", falseFlag);
173 buf.appendBody(attr.getFalseStr());
174 } else {
175 buf.appendStartTag("select");
176 buf.appendAttribute("name", elemName);
177 if (!isRequired(attr)) {
178 buf.appendOption("-", "");
179 }
180 String selectedValue = (trueFlag) ? "true" : "false";
181 if (bool == null) {
182 selectedValue = "";
183 }
184 buf.appendOption(attr.getTrueStr(), "true", selectedValue);
185 buf.appendOption(attr.getFalseStr(), "false", selectedValue);
186 buf.endTag();
187 }
188 return buf.toString();
189 }
190
191 public Object visit(DateAttribute attr, Object data) {
192 String elemName = (String) data;
193
194
195 String selectedYear = null;
196 String selectedMonth = null;
197 String selectedDate = null;
198
199 Object value = getAttributeValue(attr, elemName);
200
201 Date date = null;
202 if (value != null) {
203 date = (Date) value;
204 }
205
206 boolean nullOption = !isRequired(attr);
207
208 Calendar cal = Calendar.getInstance();
209 if (date != null) {
210 cal.setTime(date);
211 selectedYear = String.valueOf(cal.get(Calendar.YEAR));
212 selectedMonth = String.valueOf(cal.get(Calendar.MONTH) + 1);
213 selectedDate = String.valueOf(cal.get(Calendar.DATE));
214 } else if (attr.getStartValue() <= cal.get(Calendar.YEAR)
215 && attr.getEndValue() >= cal.get(Calendar.YEAR) && !nullOption) {
216 selectedYear = String.valueOf(cal.get(Calendar.YEAR));
217 selectedMonth = String.valueOf(cal.get(Calendar.MONTH) + 1);
218 selectedDate = String.valueOf(cal.get(Calendar.DATE));
219 }
220
221 return renderDateSelector(elemName, attr.getStartValue(), attr
222 .getEndValue(), nullOption, selectedYear, selectedMonth,
223 selectedDate);
224 }
225
226 private String renderDateSelector(String elemName, int startYear,
227 int endYear, boolean nullOption, String selectedYear,
228 String selectedMonth, String selectedDate) {
229
230 String onchange = ValidatorUtils.getOnChangeCalendar(elemName,
231 nullOption);
232 HtmlBuffer buf = new HtmlBuffer();
233 buf.appendSelect(elemName, startYear, endYear, selectedYear, onchange,
234 nullOption);
235 buf.appendSelect(elemName, 1, 12, selectedMonth, onchange, nullOption);
236 buf.appendSelect(elemName, 1, 31, selectedDate, onchange, nullOption);
237 return buf.toString();
238 }
239
240 public Object visit(FkAttribute field, Object data) {
241 HtmlBuffer buf = new HtmlBuffer();
242 String elemName = (String) data;
243 String fieldName = field.getName();
244
245 if (macroFlag) {
246
247 String repAttr = field.getRefEntity().getRepresentativeField();
248 if (repAttr == null) {
249 repAttr = field.getRefEntity().getFirstField().getName();
250 }
251
252 String setStmt = "$fkitms = $bean.entity.getField(\"" + fieldName
253 + "\").getDataList()";
254 String foreachStmt = "$fkitm in $fkitms";
255 String valueStmt = "${fkitm.id}";
256 String labelStmt = "${fkitm." + repAttr + "}";
257 String ifStmt = "$bean.valueObject." + fieldName + ".id == "
258 + valueStmt;
259
260 buf.appendStartTag(HtmlBuffer.TAG_SLECT);
261 buf.appendAttribute("name", elemName);
262 buf.appendBodyLine("#set(" + setStmt + ")");
263 buf.appendBodyLine("#foreach(" + foreachStmt + ")");
264 buf.appendBodyLine("#if(" + ifStmt + ")");
265 buf.appendStartTag("option");
266 buf.appendAttribute("value", valueStmt);
267 buf.appendAttribute("selected", "selected");
268 buf.appendBody(labelStmt);
269 buf.endTag();
270 buf.appendBodyLine("#else");
271 buf.appendOption(labelStmt, valueStmt);
272 buf.appendBodyLine("#end");
273 buf.appendBodyLine("#end");
274
275 buf.endTag();
276 return buf.toString();
277 } else if (bindingFkObjMap != null) {
278 Object bindingFkObj = bindingFkObjMap.get(fieldName);
279 if (bindingFkObj != null) {
280
281
282 return null;
283 }
284 }
285
286 Object fkBean = getAttributeValue(field, elemName);
287
288 Map labelValueMap = field.getLabelValueMap();
289 boolean required = isRequired(field);
290 if (labelValueMap.size() == 0 && required) {
291 buf.appendBody("no data");
292
293 } else {
294 if (searchFormFlag) {
295 Map map = new LinkedHashMap();
296 Iterator itr = labelValueMap.keySet().iterator();
297 map.put("-", "");
298 while (itr.hasNext()) {
299 Object value = itr.next();
300 map.put(value, value);
301 }
302 buf.appendSelectFromMap(elemName, map, String.valueOf(fkBean),
303 false);
304 } else {
305 Object selectedId = EntityUtils.getId(fkBean);
306 buf.appendSelectFromMap(elemName, labelValueMap, String
307 .valueOf(selectedId), !required);
308 }
309 }
310 return buf.toString();
311 }
312
313 public Object visit(FileAttribute field, Object data) {
314 String elemName = (String) data;
315 byte[] bytes = (byte[]) getAttributeValue(field, elemName);
316 HtmlBuffer buf = new HtmlBuffer();
317 if (bytes != null) {
318 SimpleFile file = (SimpleFile) CharUtil.toObject(bytes);
319 if (file.getFileName() != null && !file.getFileName().equals("")) {
320 buf.appendStartTag("a");
321 buf.appendAttribute("href", FileDownloadFunction.getHref(
322 EntityUtils.getId(valueObject), field.getEntity()
323 .getName(), field.getName()));
324 buf.appendStartTag("small");
325 buf.appendBody(file.getFileName());
326 buf.endTag();
327 buf.endTag();
328
329 String flag = FileAttribute.toFlag(elemName);
330
331 buf.appendStartTag("small");
332 buf.appendRadio(flag, FileAttribute.FLAG_NOUPDATE, true);
333 buf.appendBody(TgwResource.getMessage("filefield.noupdate"));
334 buf.endTag();
335
336 if (!field.isRequired()) {
337 buf.appendStartTag("small");
338 buf.appendRadio(flag, FileAttribute.FLAG_DELETE);
339 buf.appendBody(TgwResource.getMessage("filefield.delete"));
340 buf.endTag();
341 }
342
343 buf.appendStartTag("small");
344 buf.appendRadio(flag, FileAttribute.FLAG_UPDATE);
345 buf.appendBody(TgwResource.getMessage("filefield.update"));
346 buf.endTag();
347
348 buf.appendStartTag("input");
349 buf.appendAttribute("name", FileAttribute
350 .toUpdateFile(elemName));
351 buf.appendAttribute("type", "file");
352 buf.endTag();
353 return buf.toString();
354 }
355 }
356
357 buf.appendStartTag("input");
358 buf.appendAttribute("name", elemName);
359 buf.appendAttribute("type", "file");
360 buf.endTag();
361 return buf.toString();
362 }
363
364 public Object visit(SetAttribute attr, Object data) {
365 if (!EntityUtils.manyToManyFlag(attr)) {
366 return null;
367 }
368
369 HtmlBuffer buf = new HtmlBuffer();
370 String elemName = (String) data;
371
372 TgwAttribute theother = EntityUtils.getTheOtherAttribute(attr);
373 Set set = (Set) EntityUtils.getProperty(valueObject, attr);
374
375 if (!macroFlag) {
376 if (theother instanceof FkAttribute) {
377 FkAttribute fk = (FkAttribute) theother;
378 Map labelValueMap = fk.getLabelValueMap();
379 for (Iterator i = labelValueMap.keySet().iterator(); i
380 .hasNext();) {
381 String label = (String) i.next();
382 String value = (String) labelValueMap.get(label);
383 boolean flag = EntityUtils.contains(set, theother, value);
384 buf.appendCheckBox(elemName, value, flag);
385 buf.appendBody(label);
386 }
387 } else if (theother instanceof StringAttribute) {
388 String[] labels = ((StringAttribute) theother)
389 .getRestrictions();
390 for (int i = 0; i < labels.length; i++) {
391 boolean flag = EntityUtils.contains(set, theother,
392 labels[i]);
393 buf.appendCheckBox(elemName, labels[i], flag);
394 buf.appendBody(labels[i]);
395 if (i % 4 == 3) {
396 buf.appendBr();
397 }
398 }
399 }
400 } else {
401
402
403
404 }
405 return buf.toString();
406 }
407
408 public Object visit(SelfAttribute field, Object data) {
409 String elemName = (String) data;
410 Object selfParentObj = getAttributeValue(field, elemName);
411
412 Map labelValueMap = field.getLabelValueMap();
413 String selectedId = null;
414
415 HtmlBuffer buf = new HtmlBuffer();
416 if (selfParentObj != null) {
417 selectedId = "" + EntityUtils.getId(selfParentObj);
418 }
419 buf.appendSelectFromMap(elemName, labelValueMap, selectedId, true);
420 return buf.toString();
421 }
422
423 public Object visit(SecurityAttribute field, Object data) {
424 return null;
425 }
426
427 public Object visit(TimestampAttribute field, Object data) {
428 String elemName = (String) data;
429 return renderDateSelector(elemName, 2006, 2007, true, null, null, null);
430 }
431
432 public Object visit(DoubleAttribute field, Object data) {
433 return null;
434 }
435
436
437
438
439
440 private String renderIntegerArray(IntegerAttribute attr, String elemName) {
441 Object value = getAttributeValue(attr, elemName);
442
443 String selected = (value != null) ? value.toString() : null;
444 int min = attr.getMin();
445 int max = attr.getMax();
446 int interval = attr.getInterval();
447
448
449 HtmlBuffer buf = new HtmlBuffer();
450 buf.appendStartTag("select");
451 buf.appendAttribute("name", elemName);
452 if (!isRequired(attr)) {
453 buf.appendOption("-", "");
454 }
455 for (int i = min; i <= max; i += interval) {
456 buf.appendOption(String.valueOf(i), String.valueOf(i), selected);
457 }
458 buf.endTag();
459 return buf.toString();
460 }
461
462 private String renderStringArray(StringAttribute attr, String elemName) {
463 if (macroFlag) {
464 return renderStringArrayMacro(attr, elemName);
465 } else {
466 return renderStringArrayNotMacro(attr, elemName);
467 }
468 }
469
470 private String renderStringArrayMacro(StringAttribute attr, String elemName) {
471 HtmlBuffer buf = new HtmlBuffer();
472
473 String newElemName = attr.getName();
474
475 String setStmt = "$restrictions = $bean.entity.getField(\""
476 + newElemName + "\").getRestrictions()";
477 String setStmt2 = "$required = $bean.entity.getField(\"" + newElemName
478 + "\").isRequired()";
479 String valueStmt = "option value=\"$elemName\"";
480 String selectStmt = " selected=\"selected\"";
481 String checkStmt = " checked=\"checked\"";
482 String foreachStmt = "$elemName in $restrictions";
483 String ifStmt = "$bean.valueObject." + newElemName + " == $elemName";
484 String elseIfStmt = "$requrired && $velocityCount==1";
485 String radioStmt = "input type=\"radio\" name=\"" + elemName
486 + "\" value=\"$elemName\"";
487
488 if (!tableFormFlag
489 && StringAttribute.FORM_RADIO.equals(attr.getFormType())) {
490
491 buf.appendBodyLine("#set(" + setStmt + ")");
492 buf.appendBodyLine("#set(" + setStmt2 + ")");
493 buf.appendBodyLine("#foreach(" + foreachStmt + ")");
494 buf.appendBodyLine(" #if(" + ifStmt + ")");
495 buf.appendBodyLine(" <" + radioStmt + checkStmt + ">");
496 buf.appendBodyLine(" #elseif(" + elseIfStmt + ")");
497 buf.appendBodyLine(" <" + radioStmt + checkStmt + ">");
498 buf.appendBodyLine(" #else");
499 buf.appendBodyLine(" <" + radioStmt + ">");
500 buf.appendBodyLine(" #end");
501 buf.appendBodyLine("$elemName");
502 buf.appendBodyLine("#end");
503
504 } else {
505
506 buf.appendStartTag("select");
507 buf.appendAttribute("name", elemName);
508 if (!isRequired(attr)) {
509 buf.appendOption("-", "");
510 }
511 buf.appendBodyLine("#set(" + setStmt + ")");
512 buf.appendBodyLine("#foreach(" + foreachStmt + ")");
513 buf.appendBodyLine(" #if(" + ifStmt + ")");
514 buf.appendBodyLine(" <" + valueStmt + selectStmt + ">");
515 buf.appendBodyLine(" #else");
516 buf.appendBodyLine(" <" + valueStmt + ">");
517 buf.appendBodyLine(" #end");
518 buf.appendBodyLine(" $elemName</option>");
519 buf.appendBodyLine("#end");
520 buf.endTag();
521 }
522 return buf.toString();
523 }
524
525 private String renderStringArrayNotMacro(StringAttribute attr,
526 String elemName) {
527 String selected = (String) getAttributeValue(attr, elemName);
528
529 String[] array = attr.getRestrictions();
530
531
532 HtmlBuffer buf = new HtmlBuffer();
533 if (!tableFormFlag
534 && StringAttribute.FORM_RADIO.equals(attr.getFormType())) {
535 for (int i = 0; i < array.length; i++) {
536 boolean flag = (selected != null && selected.equals(array[i]));
537 if (isRequired(attr) && i == 0) {
538 flag = true;
539 }
540 buf.appendRadio(elemName, array[i], flag);
541 buf.appendBody(array[i]);
542 }
543 } else {
544 buf.appendStartTag("select");
545 buf.appendAttribute("name", elemName);
546 if (!isRequired(attr)) {
547 buf.appendOption("-", "");
548 }
549 for (int i = 0; i < array.length; i++) {
550 buf.appendOption(array[i], array[i], selected);
551 }
552 buf.endTag();
553 }
554 return buf.toString();
555 }
556
557 private String renderTextField(TgwAttribute attr, String elemName) {
558 Object obj = getAttributeValue(attr, elemName);
559 String valueStr = null;
560 if (obj != null) {
561 valueStr = String.valueOf(obj);
562 }
563
564 HtmlBuffer buf = new HtmlBuffer();
565 buf.appendTextField(elemName, valueStr);
566 return buf.toString();
567 }
568
569 private String renderStringTextField(StringAttribute field, String elemName) {
570 Object obj = getAttributeValue(field, elemName);
571
572 String valueStr = null;
573 if (macroFlag) {
574 valueStr = "$!{" + Constants.RATTR_VALUEOBJECT + "."
575 + field.getName() + "}";
576 } else if (obj != null) {
577 valueStr = String.valueOf(obj);
578 }
579 String mask = ((StringAttribute) field).getMask();
580
581
582 HtmlBuffer buf = new HtmlBuffer();
583 if (searchFormFlag || tableFormFlag) {
584 buf.appendTextField(elemName, ResponseUtils.filter(valueStr));
585 } else if (StringAttribute.MASK_HTML.equals(mask)) {
586 buf.appendStartTag("textarea");
587 buf.appendAttribute("name", elemName);
588 buf.appendAttribute("id", "testId");
589
590 if (macroFlag) {
591 buf.appendBody("$!{bean.valueObject." + field.getName() + "}");
592 } else {
593 buf.appendBody(" ");
594 }
595
596 buf.endTag();
597
598 buf.appendStartTag("script");
599 buf.appendAttribute("type", "text/javascript");
600
601 buf.appendBody("var htmlEditor = new FCKeditor( 'testId' );");
602 buf.appendBody("htmlEditor.BasePath = '"
603 + TgwContext.getContextPath() + "/FCKeditor/';");
604 buf.appendBody("htmlEditor.ToolbarSet = 'HtmlString';");
605 buf.appendBody("htmlEditor.ReplaceTextarea();");
606
607 buf.endTag();
608
609 } else if (StringAttribute.MASK_CONTEXT.equals(mask)
610 || StringAttribute.MASK_WIKI.equals(mask)) {
611 buf.appendTextArea(elemName, ResponseUtils.filter(valueStr),
612 DEFAULT_TEXTAREA_ROWS, DEFAULT_TEXTAREA_COLS);
613 } else if (StringAttribute.MASK_SHORTCONTEXT.equals(mask)) {
614 buf.appendTextArea(elemName, ResponseUtils.filter(valueStr));
615 } else {
616 int length = field.getLength();
617 buf.appendTextField(elemName, ResponseUtils.filter(valueStr),
618 length);
619 }
620 return buf.toString();
621 }
622
623 private String renderFkHidden(FkAttribute fkField, Object bindingFkObj,
624 String elemName) {
625
626
627
628
629
630
631
632
633
634
635 TgwEntity refEntity = fkField.getRefEntity();
636 BinaryFunction viewFunction = (BinaryFunction) refEntity.accept(
637 DefaultDataViewVisitor.INSTANCE, null);
638 Object result = viewFunction.evaluate(bindingFkObj, null);
639 if (result == null) {
640 return "";
641 }
642 return String.valueOf(result);
643
644
645
646 }
647
648 private boolean isRequired(TgwAttribute attr) {
649 return attr.isRequired() && !searchFormFlag;
650 }
651
652 private Object getAttributeValue(TgwAttribute attr, String elemName) {
653 String propName = null;
654 if (searchFormFlag) {
655 propName = elemName;
656 if (EntityUtils.needConverter(attr)) {
657 propName = TgwNameUtils.getOritinalConverterFieldName(elemName);
658 }
659 } else {
660 propName = attr.getName();
661 }
662 return EntityUtils.getProperty(valueObject, propName);
663 }
664 }