/* * Copyright 2011 cruxframework.org. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.cruxframework.crux.gwt.rebind; import java.util.ArrayList; import org.cruxframework.crux.core.client.utils.EscapeUtils; import org.cruxframework.crux.core.client.utils.StringUtils; import org.cruxframework.crux.core.rebind.AbstractProxyCreator.SourcePrinter; import org.cruxframework.crux.core.rebind.CruxGeneratorException; import org.cruxframework.crux.core.rebind.cell.CustomCellScanner; import org.cruxframework.crux.core.rebind.screen.widget.EvtProcessor; import org.cruxframework.crux.core.rebind.screen.widget.WidgetCreator; import org.cruxframework.crux.core.rebind.screen.widget.WidgetCreatorContext; import org.cruxframework.crux.core.rebind.screen.widget.creator.children.ChoiceChildProcessor; import org.cruxframework.crux.core.rebind.screen.widget.creator.children.WidgetChildProcessor; import org.cruxframework.crux.core.rebind.screen.widget.declarative.TagAttributeDeclaration; import org.cruxframework.crux.core.rebind.screen.widget.declarative.TagAttributesDeclaration; import org.cruxframework.crux.core.rebind.screen.widget.declarative.TagChild; import org.cruxframework.crux.core.rebind.screen.widget.declarative.TagChildren; import org.cruxframework.crux.core.rebind.screen.widget.declarative.TagConstraints; import org.cruxframework.crux.gwt.client.DateFormatUtil; import org.cruxframework.crux.gwt.client.NumberFormatUtil; import org.json.JSONArray; import org.json.JSONObject; import com.google.gwt.cell.client.AbstractCell; import com.google.gwt.cell.client.ActionCell; import com.google.gwt.cell.client.ActionCell.Delegate; import com.google.gwt.cell.client.ButtonCell; import com.google.gwt.cell.client.CheckboxCell; import com.google.gwt.cell.client.ClickableTextCell; import com.google.gwt.cell.client.DateCell; import com.google.gwt.cell.client.DatePickerCell; import com.google.gwt.cell.client.EditTextCell; import com.google.gwt.cell.client.ImageCell; import com.google.gwt.cell.client.ImageLoadingCell; import com.google.gwt.cell.client.ImageResourceCell; import com.google.gwt.cell.client.NumberCell; import com.google.gwt.cell.client.SafeHtmlCell; import com.google.gwt.cell.client.SelectionCell; import com.google.gwt.cell.client.TextCell; import com.google.gwt.cell.client.TextInputCell; /** * @author Thiago da Rosa de Bustamante * */ @SuppressWarnings("deprecation") @TagAttributesDeclaration({ @TagAttributeDeclaration(value="dataObject", required=true) }) public abstract class AbstractCellFactory<C extends WidgetCreatorContext> extends WidgetCreator<C> { private CustomCellScanner customCells; public AbstractCellFactory() { customCells = new CustomCellScanner(getContext().getGeneratorContext()); } /** * @param metaElem * @return */ protected String getDataObject(JSONObject metaElem) { String dataObject = metaElem.optString("dataObject"); String dataObjectClass = getContext().getDataObjects().getDataObject(dataObject); if (StringUtils.isEmpty(dataObjectClass)) { throw new CruxGeneratorException("DataObject ["+dataObject+"], referenced by widget ["+metaElem.optString("id")+"] not found."); } return dataObjectClass; } /** * @param out * @param metaElem * @return */ protected String getCell(SourcePrinter out, JSONObject metaElem, String parentWidgetId) { JSONObject child = ensureFirstChild(metaElem, false, parentWidgetId); String childName = getChildName(child); String cell = createVariableName("cell"); out.print(AbstractCell.class.getCanonicalName()+" "+cell+"=("+AbstractCell.class.getCanonicalName()+")"); if (childName.equals("customCell")) { getCustomCell(out, child); } else if (childName.equals("buttonCell")) { out.println("new "+ButtonCell.class.getCanonicalName()+"();"); } else if (childName.equals("textCell")) { out.println("new "+TextCell.class.getCanonicalName()+"();"); } else if (childName.equals("clickableTextCell")) { out.println("new "+ClickableTextCell.class.getCanonicalName()+"();"); } else if (childName.equals("selectionCell")) { getSelectionCell(out, child, parentWidgetId); } else if (childName.equals("textInputCell")) { out.println("new "+TextInputCell.class.getCanonicalName()+"();"); } else if (childName.equals("checkboxCell")) { getCheckboxCell(out, child); } else if (childName.equals("datePickerCell")) { getDatePickerCell(out, child); } else if (childName.equals("editTextCell")) { out.println("new "+EditTextCell.class.getCanonicalName()+"();"); } else if (childName.equals("actionCell")) { getActionCell(out, child, metaElem); } else if (childName.equals("dateCell")) { getDateCell(out, child); } else if (childName.equals("imageCell")) { out.println("new "+ImageCell.class.getCanonicalName()+"();"); } else if (childName.equals("imageLoadingCell")) { out.println("new "+ImageLoadingCell.class.getCanonicalName()+"();"); } else if (childName.equals("imageResourceCell")) { out.println("new "+ImageResourceCell.class.getCanonicalName()+"();"); } else if (childName.equals("numberCell")) { getNumberCell(out, child); } else if (childName.equals("safeHtmlCell")) { out.println("new "+SafeHtmlCell.class.getCanonicalName()+"();"); } else { out.println("null;"); } return cell; } /** * @param out * @param metaElem */ protected void getNumberCell(SourcePrinter out, JSONObject metaElem) { String numberPattern = metaElem.optString("numberPattern"); if (numberPattern == null || numberPattern.length() == 0) { numberPattern = NumberFormatUtil.DECIMAL_PATTERN; } out.println("new "+NumberCell.class.getCanonicalName()+"("+NumberFormatUtil.class.getCanonicalName()+".getNumberFormat("+ EscapeUtils.quote(numberPattern)+"));"); } /** * @param out * @param child * @param parentMetaElem */ protected void getActionCell(SourcePrinter out, JSONObject child, JSONObject parentMetaElem) { String text = child.optString("text"); String delegateMethod = child.optString("delegateMethod"); assert (!StringUtils.isEmpty(delegateMethod) && (!StringUtils.isEmpty(text))); String dataObjectClass = getDataObject(parentMetaElem); out.println("new "+ActionCell.class.getCanonicalName()+"<"+dataObjectClass+">("+EscapeUtils.quote(text)+ ", new "+Delegate.class.getCanonicalName()+"<"+dataObjectClass+">(){"); out.println("void execute("+dataObjectClass+" object){"); EvtProcessor.printEvtCall(out, delegateMethod, "loadCell", dataObjectClass, "object", this); out.println("}"); out.println(");"); } /** * @param out * @param child */ protected void getDatePickerCell(SourcePrinter out, JSONObject child) { String datePattern = child.optString("datePattern"); if (datePattern == null || datePattern.length() == 0) { datePattern = DateFormatUtil.MEDIUM_DATE_PATTERN; } out.println("new "+DatePickerCell.class.getCanonicalName()+"("+DateFormatUtil.class.getCanonicalName()+".getDateTimeFormat("+ EscapeUtils.quote(datePattern)+"));"); } /** * @param out * @param child */ protected void getDateCell(SourcePrinter out, JSONObject child) { String datePattern = child.optString("datePattern"); if (datePattern == null || datePattern.length() == 0) { datePattern = DateFormatUtil.MEDIUM_DATE_PATTERN; } out.println("new "+DateCell.class.getCanonicalName()+"("+DateFormatUtil.class.getCanonicalName()+".getDateTimeFormat("+ EscapeUtils.quote(datePattern)+"));"); } /** * @param out * @param child */ protected void getCheckboxCell(SourcePrinter out, JSONObject child) { boolean dependsOnSelection = false; String dependsOnSelectionStr = child.optString("dependsOnSelection"); if (StringUtils.isEmpty(dependsOnSelectionStr)) { dependsOnSelection = Boolean.parseBoolean(dependsOnSelectionStr); } boolean handlesSelection = dependsOnSelection; String handlesSelectionStr = child.optString("handlesSelection"); if (StringUtils.isEmpty(handlesSelectionStr)) { handlesSelection = Boolean.parseBoolean(handlesSelectionStr); } out.println("new "+CheckboxCell.class.getCanonicalName()+"("+dependsOnSelection+", "+handlesSelection+");"); } /** * @param out * @param child */ protected void getSelectionCell(SourcePrinter out, JSONObject child, String parentWidgetId) { String options = createVariableName("options"); out.println(ArrayList.class.getCanonicalName()+"<String> "+options+" = "+ArrayList.class.getCanonicalName()+"<String>();"); JSONArray children = ensureChildren(child, true, parentWidgetId); if (children != null) { for (int i=0; i< children.length(); i++) { JSONObject optionElement = children.optJSONObject(i); String textOption = ensureTextChild(optionElement, true, parentWidgetId, true); if (textOption != null) { out.println(options+".add("+textOption+");"); } } } out.println("new "+SelectionCell.class.getCanonicalName()+"("+options+");"); } /** * @param out * @param child */ protected void getCustomCell(SourcePrinter out, JSONObject child) { String cellName = child.optString("cellName"); assert (!StringUtils.isEmpty(cellName)); out.println("new "+customCells.getCustomCell(cellName)+"();"); //TODO validar se o tipo do objeto informado no dataObject é compatível com o tipo do objeto renderizado pelo customCell (e também pelo dataProvider) } /** * @author Thiago da Rosa de Bustamante * */ @TagConstraints(minOccurs="1", maxOccurs="1") @TagChildren({ @TagChild(CustomCellProcessor.class), @TagChild(ButtonCellProcessor.class), @TagChild(TextCellProcessor.class), @TagChild(ClickableTextCellProcessor.class), @TagChild(SelectionCellProcessor.class), @TagChild(TextInputCellProcessor.class), @TagChild(CheckboxCellProcessor.class), @TagChild(DatePickerCellProcessor.class), @TagChild(EditTextCellProcessor.class), @TagChild(ActionCellProcessor.class), @TagChild(DateCellProcessor.class), @TagChild(ImageCellProcessor.class), @TagChild(ImageLoadingCellProcessor.class), @TagChild(ImageResourceCellProcessor.class), @TagChild(NumberCellProcessor.class), @TagChild(SafeHtmlCellProcessor.class) }) public static class CellListChildProcessor extends ChoiceChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="customCell") @TagAttributesDeclaration({ @TagAttributeDeclaration(value="cellName", required=true) }) public static class CustomCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="buttonCell") public static class ButtonCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="textCell") public static class TextCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="clickableTextCell") public static class ClickableTextCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="selectionCell") @TagChildren({ @TagChild(ListOptionProcessor.class) }) public static class SelectionCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="option", type=String.class, minOccurs="0", maxOccurs="unbounded") public static class ListOptionProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="textInputCell") public static class TextInputCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="checkboxCell") @TagAttributesDeclaration({ @TagAttributeDeclaration(value="dependsOnSelection", type=Boolean.class), @TagAttributeDeclaration(value="handlesSelection", type=Boolean.class) }) public static class CheckboxCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="datePickerCell") @TagAttributesDeclaration({ @TagAttributeDeclaration("datePattern") }) public static class DatePickerCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="editTextCell") public static class EditTextCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="actionCell") @TagAttributesDeclaration({ @TagAttributeDeclaration(value="text", required=true), @TagAttributeDeclaration(value="delegateMethod", required=true) }) public static class ActionCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} /* @TagConstraints(tagName="compositeCell") @TagChildren({ @TagChild(CompositeChildProcessor.class) }) public static class CompositeCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="column") @TagAttributesDeclaration({ @TagAttributeDeclaration(value="horizontalAlignment", required=true), @TagAttributeDeclaration(value="verticalAlignment", required=true)//TODO: e o fieldUpdater??? }) @TagChildren({ @TagChild(CellListChildProcessor.class) }) public static class CompositeChildProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} */ @TagConstraints(tagName="dateCell") @TagAttributesDeclaration({ @TagAttributeDeclaration("datePattern") }) public static class DateCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="imageCell") public static class ImageCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="imageLoadingCell") public static class ImageLoadingCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="imageResourceCell") public static class ImageResourceCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="numberCell") @TagAttributesDeclaration({ @TagAttributeDeclaration("numberPattern") }) public static class NumberCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} @TagConstraints(tagName="safeHtmlCell") public static class SafeHtmlCellProcessor extends WidgetChildProcessor<WidgetCreatorContext> {} }