bug 399381: Bean-based table field data and name-based import/export of table data
https://bugs.eclipse.org/bugs/show_bug.cgi?id=399381
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/forms/replace/TableFieldBaseForm.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/forms/replace/TableFieldBaseForm.java
new file mode 100644
index 0000000..becde4d
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/forms/replace/TableFieldBaseForm.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package formdata.client.ui.forms.replace;
+
+import org.eclipse.scout.commons.annotations.FormData;
+import org.eclipse.scout.commons.annotations.FormData.SdkCommand;
+import org.eclipse.scout.commons.annotations.Order;
+import org.eclipse.scout.commons.exception.ProcessingException;
+import org.eclipse.scout.rt.client.ui.basic.table.AbstractTable;
+import org.eclipse.scout.rt.client.ui.basic.table.ITable;
+import org.eclipse.scout.rt.client.ui.basic.table.columns.AbstractStringColumn;
+import org.eclipse.scout.rt.client.ui.form.AbstractForm;
+import org.eclipse.scout.rt.client.ui.form.fields.groupbox.AbstractGroupBox;
+import org.eclipse.scout.rt.client.ui.form.fields.tablefield.AbstractTableField;
+import org.eclipse.scout.rt.shared.data.form.fields.tablefield.AbstractTableFieldBeanData;
+
+import formdata.shared.services.process.replace.TableFieldBaseFormData;
+
+@FormData(value = TableFieldBaseFormData.class, sdkCommand = SdkCommand.CREATE)
+public class TableFieldBaseForm extends AbstractForm {
+
+ /**
+ * @throws ProcessingException
+ */
+ public TableFieldBaseForm() throws ProcessingException {
+ super();
+ }
+
+ @Order(10.0)
+ public class MainBox extends AbstractGroupBox {
+
+ @Order(10.0)
+ @FormData(sdkCommand = SdkCommand.USE, value = AbstractTableFieldBeanData.class)
+ public class TableField extends AbstractTableField<TableField.Table> {
+
+ public class Table extends AbstractTable {
+
+ @Order(10.0)
+ public class FirstColumn extends AbstractStringColumn {
+
+ }
+
+ @Order(20.0)
+ public class SecondColumn extends AbstractStringColumn {
+
+ }
+ }
+ }
+
+ @Order(20.0)
+ @FormData(sdkCommand = SdkCommand.USE, value = AbstractTableFieldBeanData.class)
+ public class EmptyTableField extends AbstractTableField<EmptyTableField.Table> {
+
+ public class Table extends AbstractTable {
+ }
+ }
+
+ @Order(30.0)
+ @FormData(sdkCommand = SdkCommand.USE, value = AbstractTableFieldBeanData.class)
+ public class NoTableField extends AbstractTableField<ITable> {
+ }
+ }
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/forms/replace/TableFieldExForm.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/forms/replace/TableFieldExForm.java
new file mode 100644
index 0000000..efeebff
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.client/src/formdata/client/ui/forms/replace/TableFieldExForm.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package formdata.client.ui.forms.replace;
+
+import org.eclipse.scout.commons.annotations.FormData;
+import org.eclipse.scout.commons.annotations.FormData.SdkCommand;
+import org.eclipse.scout.commons.annotations.Order;
+import org.eclipse.scout.commons.annotations.Replace;
+import org.eclipse.scout.commons.exception.ProcessingException;
+import org.eclipse.scout.rt.client.ui.basic.table.AbstractTable;
+import org.eclipse.scout.rt.client.ui.basic.table.columns.AbstractBooleanColumn;
+import org.eclipse.scout.rt.client.ui.basic.table.columns.AbstractStringColumn;
+
+import formdata.shared.services.process.replace.TableFieldExFormData;
+
+/**
+ *
+ */
+@FormData(value = TableFieldExFormData.class, sdkCommand = SdkCommand.CREATE)
+public class TableFieldExForm extends TableFieldBaseForm {
+
+ public TableFieldExForm() throws ProcessingException {
+ super();
+ }
+
+ @Replace
+ public class TableExtendedField extends TableFieldBaseForm.MainBox.TableField {
+
+ public TableExtendedField(TableFieldBaseForm.MainBox container) {
+ container.super();
+ }
+
+ public class TableEx extends Table {
+
+ @Order(30)
+ @Replace
+ public class FirstExtendedColumn extends FirstColumn {
+
+ }
+
+ @Order(40)
+ public class BooleanColumn extends AbstractBooleanColumn {
+
+ }
+ }
+ }
+
+ @Replace
+ public class EmptyTableExtendedField extends TableFieldBaseForm.MainBox.EmptyTableField {
+
+ public EmptyTableExtendedField(TableFieldBaseForm.MainBox container) {
+ container.super();
+ }
+
+ public class TableEx extends Table {
+
+ public class SingleColumn extends AbstractStringColumn {
+
+ }
+ }
+ }
+
+ @Replace
+ public class NoTableExtendedField extends TableFieldBaseForm.MainBox.NoTableField {
+
+ public NoTableExtendedField(TableFieldBaseForm.MainBox container) {
+ container.super();
+ }
+
+ public class Table extends AbstractTable {
+
+ public class NewColumn extends AbstractStringColumn {
+
+ }
+ }
+ }
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/services/process/replace/TableFieldBaseFormData.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/services/process/replace/TableFieldBaseFormData.java
new file mode 100644
index 0000000..cd06bb8
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/services/process/replace/TableFieldBaseFormData.java
@@ -0,0 +1,158 @@
+package formdata.shared.services.process.replace;
+
+import org.eclipse.scout.rt.shared.data.basic.table.AbstractTableRowData;
+import org.eclipse.scout.rt.shared.data.form.AbstractFormData;
+import org.eclipse.scout.rt.shared.data.form.fields.tablefield.AbstractTableFieldBeanData;
+
+public class TableFieldBaseFormData extends AbstractFormData {
+ private static final long serialVersionUID = 1L;
+
+ public TableFieldBaseFormData() {
+ }
+
+ public EmptyTable getEmptyTable() {
+ return getFieldByClass(EmptyTable.class);
+ }
+
+ public NoTable getNoTable() {
+ return getFieldByClass(NoTable.class);
+ }
+
+ public Table getTable() {
+ return getFieldByClass(Table.class);
+ }
+
+ public static class EmptyTable extends AbstractTableFieldBeanData {
+ private static final long serialVersionUID = 1L;
+
+ public EmptyTable() {
+ }
+
+ @Override
+ public EmptyTableRowData addRow(int rowState) {
+ return (EmptyTableRowData) super.addRow(rowState);
+ }
+
+ @Override
+ public EmptyTableRowData addRow() {
+ return (EmptyTableRowData) super.addRow();
+ }
+
+ @Override
+ public EmptyTableRowData createRow() {
+ return new EmptyTableRowData();
+ }
+
+ @Override
+ public Class<? extends AbstractTableRowData> getRowType() {
+ return EmptyTableRowData.class;
+ }
+
+ @Override
+ public EmptyTableRowData[] getRows() {
+ return (EmptyTableRowData[]) super.getRows();
+ }
+
+ @Override
+ public EmptyTableRowData rowAt(int idx) {
+ return (EmptyTableRowData) super.rowAt(idx);
+ }
+
+ public void setRows(EmptyTableRowData[] rows) {
+ super.setRows(rows);
+ }
+
+ public static class EmptyTableRowData extends AbstractTableRowData {
+ private static final long serialVersionUID = 1L;
+
+ public EmptyTableRowData() {
+ }
+ }
+ }
+
+ public static class NoTable extends AbstractTableFieldBeanData {
+ private static final long serialVersionUID = 1L;
+
+ public NoTable() {
+ }
+
+ @Override
+ public AbstractTableRowData createRow() {
+ return new AbstractTableRowData() {
+ private static final long serialVersionUID = 1L;
+ };
+ }
+
+ @Override
+ public Class<? extends AbstractTableRowData> getRowType() {
+ return AbstractTableRowData.class;
+ }
+ }
+
+ public static class Table extends AbstractTableFieldBeanData {
+ private static final long serialVersionUID = 1L;
+
+ public Table() {
+ }
+
+ @Override
+ public TableRowData addRow() {
+ return (TableRowData) super.addRow();
+ }
+
+ @Override
+ public TableRowData addRow(int rowState) {
+ return (TableRowData) super.addRow(rowState);
+ }
+
+ @Override
+ public TableRowData createRow() {
+ return new TableRowData();
+ }
+
+ @Override
+ public Class<? extends AbstractTableRowData> getRowType() {
+ return TableRowData.class;
+ }
+
+ @Override
+ public TableRowData[] getRows() {
+ return (TableRowData[]) super.getRows();
+ }
+
+ @Override
+ public TableRowData rowAt(int idx) {
+ return (TableRowData) super.rowAt(idx);
+ }
+
+ public void setRows(TableRowData[] rows) {
+ super.setRows(rows);
+ }
+
+ public static class TableRowData extends AbstractTableRowData {
+ private static final long serialVersionUID = 1L;
+
+ public TableRowData() {
+ }
+
+ private String m_first;
+ private String m_second;
+
+ public String getFirst() {
+ return m_first;
+ }
+
+ public void setFirst(String first) {
+ m_first = first;
+ }
+
+ public String getSecond() {
+ return m_second;
+ }
+
+ public void setSecond(String second) {
+ m_second = second;
+ }
+ }
+ }
+}
diff --git a/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/services/process/replace/TableFieldExFormData.java b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/services/process/replace/TableFieldExFormData.java
new file mode 100644
index 0000000..658d8cf
--- /dev/null
+++ b/org.eclipse.scout.sdk.test/resources/operation/formData/formdata.shared/src/formdata/shared/services/process/replace/TableFieldExFormData.java
@@ -0,0 +1,200 @@
+package formdata.shared.services.process.replace;
+
+import org.eclipse.scout.commons.annotations.Replace;
+import org.eclipse.scout.rt.shared.data.basic.table.AbstractTableRowData;
+
+public class TableFieldExFormData extends TableFieldBaseFormData {
+ private static final long serialVersionUID = 1L;
+
+ public TableFieldExFormData() {
+ }
+
+ public EmptyTableExtended getEmptyTableExtended() {
+ return getFieldByClass(EmptyTableExtended.class);
+ }
+
+ public NoTableExtended getNoTableExtended() {
+ return getFieldByClass(NoTableExtended.class);
+ }
+
+ public TableExtended getTableExtended() {
+ return getFieldByClass(TableExtended.class);
+ }
+
+ @Replace
+ public static class EmptyTableExtended extends TableFieldBaseFormData.EmptyTable {
+ private static final long serialVersionUID = 1L;
+
+ public EmptyTableExtended() {
+ }
+
+ @Override
+ public TableExRowData addRow() {
+ return (TableExRowData) super.addRow();
+ }
+
+ @Override
+ public TableExRowData addRow(int rowState) {
+ return (TableExRowData) super.addRow(rowState);
+ }
+
+ @Override
+ public TableExRowData createRow() {
+ return new TableExRowData();
+ }
+
+ @Override
+ public Class<? extends AbstractTableRowData> getRowType() {
+ return TableExRowData.class;
+ }
+
+ @Override
+ public TableExRowData[] getRows() {
+ return (TableExRowData[]) super.getRows();
+ }
+
+ @Override
+ public TableExRowData rowAt(int idx) {
+ return (TableExRowData) super.rowAt(idx);
+ }
+
+ public void setRows(TableExRowData[] rows) {
+ super.setRows(rows);
+ }
+
+ public static class TableExRowData extends TableFieldBaseFormData.EmptyTable.EmptyTableRowData {
+ private static final long serialVersionUID = 1L;
+
+ public TableExRowData() {
+ }
+
+ private String m_single;
+
+ public void setSingle(String single) {
+ m_single = single;
+ }
+
+ public String getSingle() {
+ return m_single;
+ }
+ }
+ }
+
+ @Replace
+ public static class NoTableExtended extends TableFieldBaseFormData.NoTable {
+ private static final long serialVersionUID = 1L;
+
+ public NoTableExtended() {
+ }
+
+ @Override
+ public NoTableExtendedRowData addRow() {
+ return (NoTableExtendedRowData) super.addRow();
+ }
+
+ @Override
+ public NoTableExtendedRowData addRow(int rowState) {
+ return (NoTableExtendedRowData) super.addRow(rowState);
+ }
+
+ @Override
+ public NoTableExtendedRowData createRow() {
+ return new NoTableExtendedRowData();
+ }
+
+ @Override
+ public Class<? extends AbstractTableRowData> getRowType() {
+ return NoTableExtendedRowData.class;
+ }
+
+ @Override
+ public NoTableExtendedRowData[] getRows() {
+ return (NoTableExtendedRowData[]) super.getRows();
+ }
+
+ @Override
+ public NoTableExtendedRowData rowAt(int idx) {
+ return (NoTableExtendedRowData) super.rowAt(idx);
+ }
+
+ public void setRows(NoTableExtendedRowData[] rows) {
+ super.setRows(rows);
+ }
+
+ public static class NoTableExtendedRowData extends AbstractTableRowData {
+ private static final long serialVersionUID = 1L;
+
+ public NoTableExtendedRowData() {
+ }
+
+ private String m_newValue;
+
+ public void setNew(String newValue) {
+ m_newValue = newValue;
+ }
+
+ public String getNew() {
+ return m_newValue;
+ }
+ }
+ }
+
+ @Replace
+ public static class TableExtended extends TableFieldBaseFormData.Table {
+ private static final long serialVersionUID = 1L;
+
+ public TableExtended() {
+ }
+
+ @Override
+ public TableExRowData addRow(int rowState) {
+ return (TableExRowData) super.addRow(rowState);
+ }
+
+ @Override
+ public TableExRowData addRow() {
+ return (TableExRowData) super.addRow();
+ }
+
+ @Override
+ public TableExRowData createRow() {
+ return new TableExRowData();
+ }
+
+ @Override
+ public Class<? extends AbstractTableRowData> getRowType() {
+ return TableExRowData.class;
+ }
+
+ @Override
+ public TableExRowData[] getRows() {
+ return (TableExRowData[]) super.getRows();
+ }
+
+ @Override
+ public TableExRowData rowAt(int idx) {
+ return (TableExRowData) super.rowAt(idx);
+ }
+
+ public void setRows(TableExRowData[] rows) {
+ super.setRows(rows);
+ }
+
+ public static class TableExRowData extends TableFieldBaseFormData.Table.TableRowData {
+ private static final long serialVersionUID = 1L;
+
+ public TableExRowData() {
+ }
+
+ private Boolean m_booleanValue;
+
+ public void setBoolean(Boolean booleanValue) {
+ m_booleanValue = booleanValue;
+ }
+
+ public Boolean getBoolean() {
+ return m_booleanValue;
+ }
+ }
+ }
+}
diff --git a/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/RuntimeClasses.java b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/RuntimeClasses.java
index 54119c2..ac243e9 100644
--- a/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/RuntimeClasses.java
+++ b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/RuntimeClasses.java
@@ -115,6 +115,8 @@
public static final String AbstractTable = "org.eclipse.scout.rt.client.ui.basic.table.AbstractTable"; // NO_UCD
public static final String AbstractTableField = "org.eclipse.scout.rt.client.ui.form.fields.tablefield.AbstractTableField"; // NO_UCD
public static final String AbstractTableFieldData = "org.eclipse.scout.rt.shared.data.form.fields.tablefield.AbstractTableFieldData"; // NO_UCD
+ public static final String AbstractTableFieldBeanData = "org.eclipse.scout.rt.shared.data.form.fields.tablefield.AbstractTableFieldBeanData"; // NO_UCD
+ public static final String AbstractTableRowData = "org.eclipse.scout.rt.shared.data.basic.table.AbstractTableRowData"; // NO_UCD
public static final String AbstractTimeField = "org.eclipse.scout.rt.client.ui.form.fields.timefield.AbstractTimeField"; // NO_UCD
public static final String AbstractToolButton = "org.eclipse.scout.rt.client.ui.action.tool.AbstractToolButton"; // NO_UCD
public static final String AbstractTree = "org.eclipse.scout.rt.client.ui.basic.tree.AbstractTree"; // NO_UCD
diff --git a/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/FieldSourceBuilder.java b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/FieldSourceBuilder.java
new file mode 100644
index 0000000..f57ba2d
--- /dev/null
+++ b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/FieldSourceBuilder.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.sdk.operation.form.formdata;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.scout.sdk.util.signature.IImportValidator;
+import org.eclipse.scout.sdk.util.signature.SignatureUtility;
+
+/**
+ * Source builder for java field declarations (without getter and setter methods). By default, a private non-static
+ * and non-final field is created.
+ *
+ * @since 3.8.2
+ */
+public class FieldSourceBuilder implements ISourceBuilder {
+
+ private String m_elementName;
+ private String m_signature;
+ private int m_flags;
+
+ public FieldSourceBuilder() {
+ // defaults
+ m_flags = Flags.AccPrivate;
+ }
+
+ @Override
+ public String createSource(IImportValidator validator) throws JavaModelException {
+ StringBuilder builder = new StringBuilder();
+ if (Flags.isPublic(getFlags())) {
+ builder.append("public ");
+ }
+ if (Flags.isPrivate(getFlags())) {
+ builder.append("private ");
+ }
+ if (Flags.isProtected(getFlags())) {
+ builder.append("protected ");
+ }
+ if (Flags.isStatic(getFlags())) {
+ builder.append("static ");
+ }
+ if (Flags.isFinal(getFlags())) {
+ builder.append("final ");
+ }
+ builder.append(SignatureUtility.getTypeReference(getSignature(), validator) + " ");
+ builder.append(getElementName() + ";");
+ return builder.toString();
+ }
+
+ @Override
+ public int getType() {
+ return PROPERTY_SOURCE_BUILDER;
+ }
+
+ @Override
+ public String getElementName() {
+ return m_elementName;
+ }
+
+ public void setElementName(String elementName) {
+ m_elementName = elementName;
+ }
+
+ public String getSignature() {
+ return m_signature;
+ }
+
+ public void setSignature(String signature) {
+ m_signature = signature;
+ }
+
+ public int getFlags() {
+ return m_flags;
+ }
+
+ public void setFlags(int flags) {
+ m_flags = flags;
+ }
+}
diff --git a/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/FormDataUtility.java b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/FormDataUtility.java
index 53168d2..4dd9d56 100644
--- a/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/FormDataUtility.java
+++ b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/FormDataUtility.java
@@ -114,6 +114,9 @@
if (superTypeHierarchy != null && superTypeHierarchy.contains(TypeUtility.getType(RuntimeClasses.AbstractTableFieldData))) {
builder = new TableFieldSourceBuilder(formField, hierarchy);
}
+ else if (superTypeHierarchy != null && superTypeHierarchy.contains(TypeUtility.getType(RuntimeClasses.AbstractTableFieldBeanData))) {
+ builder = new TableFieldBeanSourceBuilder(formField, hierarchy);
+ }
else {
builder = new CompositePrimaryTypeSourceBuilder(formField, hierarchy);
}
@@ -135,6 +138,9 @@
if (superTypeHierarchy != null && superTypeHierarchy.contains(TypeUtility.getType(RuntimeClasses.AbstractTableFieldData))) {
builder = new TableFieldSourceBuilder(formField, hierarchy);
}
+ else if (superTypeHierarchy != null && superTypeHierarchy.contains(TypeUtility.getType(RuntimeClasses.AbstractTableFieldBeanData))) {
+ builder = new TableFieldBeanSourceBuilder(formField, hierarchy);
+ }
else {
builder = new SourceBuilderWithProperties(formField);
}
diff --git a/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/ISourceBuilder.java b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/ISourceBuilder.java
index d41fb1a..1d528a1 100644
--- a/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/ISourceBuilder.java
+++ b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/ISourceBuilder.java
@@ -21,6 +21,7 @@
public static final int METHOD_SOURCE_BUILDER = 2;
public static final int ANNOTATION_SOURCE_BUILDER = 3;
public static final int CONSTANT_INT_SOURCE_BUILDER = 3;
+ public static final int PROPERTY_SOURCE_BUILDER = 5;
String getElementName();
diff --git a/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/TableFieldBeanSourceBuilder.java b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/TableFieldBeanSourceBuilder.java
new file mode 100644
index 0000000..9742782
--- /dev/null
+++ b/org.eclipse.scout.sdk/src/org/eclipse/scout/sdk/operation/form/formdata/TableFieldBeanSourceBuilder.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2010 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.scout.sdk.operation.form.formdata;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.scout.commons.CompositeObject;
+import org.eclipse.scout.sdk.RuntimeClasses;
+import org.eclipse.scout.sdk.internal.ScoutSdk;
+import org.eclipse.scout.sdk.util.signature.SignatureUtility;
+import org.eclipse.scout.sdk.util.type.TypeFilters;
+import org.eclipse.scout.sdk.util.type.TypeUtility;
+import org.eclipse.scout.sdk.util.typecache.ITypeHierarchy;
+import org.eclipse.scout.sdk.workspace.type.ScoutTypeComparators;
+import org.eclipse.scout.sdk.workspace.type.ScoutTypeUtility;
+
+/**
+ * Source builder that creates form data classes for an ITableField. The generated form data element stores the data in
+ * ordinary java beans (which are implementing {@link RuntimeClasses#AbstractTableRowData}.
+ *
+ * @since 3.8.2
+ */
+public class TableFieldBeanSourceBuilder extends SourceBuilderWithProperties {
+ private static final String TABLE_ROW_BEAN_SUFFIX = "RowData";
+ private final IType iTable = TypeUtility.getType(RuntimeClasses.ITable);
+ private final IType iColumn = TypeUtility.getType(RuntimeClasses.IColumn);
+
+ public TableFieldBeanSourceBuilder(IType tableField, ITypeHierarchy hierarchy) {
+ super(tableField);
+ // find table
+ IType table = findTable(tableField, hierarchy);
+ if (TypeUtility.exists(table)) {
+ visitTable(table, hierarchy);
+ }
+ else {
+ visitTable(null, hierarchy);
+ }
+ }
+
+ private IType findTable(IType tableField, ITypeHierarchy hierarchy) {
+ if (TypeUtility.exists(tableField)) {
+ IType[] tables = TypeUtility.getInnerTypes(tableField, TypeFilters.getSubtypeFilter(iTable, hierarchy), null);
+ if (tables.length > 0) {
+ if (tables.length > 1) {
+ ScoutSdk.logWarning("table field '" + tableField.getFullyQualifiedName() + "' contatins more than one table! Taking first for formdata creation.");
+ }
+ return tables[0];
+ }
+ else {
+ return findTable(hierarchy.getSuperclass(tableField), hierarchy);
+ }
+ }
+ return null;
+ }
+
+ protected void visitTable(IType table, ITypeHierarchy hierarchy) {
+ if (table == null) {
+ // createRow
+ String simpleTableRowDataName = RuntimeClasses.AbstractTableRowData.substring(RuntimeClasses.AbstractTableRowData.lastIndexOf(".") + 1);
+ MethodSourceBuilder createRow = addMethodOverride("createRow");
+ createRow.setReturnSignature(Signature.createTypeSignature(RuntimeClasses.AbstractTableRowData, true));
+ createRow.setSimpleBody("return new " + simpleTableRowDataName + "() {private static final long serialVersionUID = 1L;};");
+
+ // getRowType
+ MethodSourceBuilder getRowType = addMethodOverride("getRowType");
+ getRowType.setReturnSignature(Signature.createTypeSignature(Class.class.getName() + "<? extends " + RuntimeClasses.AbstractTableRowData + ">", true));
+ getRowType.setSimpleBody("return " + simpleTableRowDataName + ".class;");
+
+ return;
+ }
+
+ final IType[] columns = TypeUtility.getInnerTypes(table, TypeFilters.getSubtypeFilter(iColumn, hierarchy), ScoutTypeComparators.getOrderAnnotationComparator());
+
+ // table bean
+ String tableRowBeanName = getTableRowBeanName(table);
+ String tableBeanSignature = Signature.createTypeSignature(tableRowBeanName, false);
+ String tableBeanArraySignature = Signature.createArraySignature(tableBeanSignature, 1);
+
+ TypeSourceBuilder tableBeanBuilder = new TypeSourceBuilder(NL);
+ tableBeanBuilder.setElementName(tableRowBeanName);
+ tableBeanBuilder.setSuperTypeSignature(getTableRowDataSuperClassSignature(table, hierarchy));
+ tableBeanBuilder.setFlags(Flags.AccPublic | Flags.AccStatic);
+ addBuilder(tableBeanBuilder, CATEGORY_TYPE_FIELD);
+
+ for (int i = 0; i < columns.length; i++) {
+ IType column = columns[i];
+ try {
+ if (ScoutTypeUtility.isReplaceAnnotationPresent(column)) {
+ // replaced columns already have a column data
+ continue;
+ }
+
+ String upperColName = FormDataUtility.getBeanName(FormDataUtility.getFieldNameWithoutSuffix(column.getElementName()), true);
+ String lowerColName = FormDataUtility.getBeanName(FormDataUtility.getFieldNameWithoutSuffix(column.getElementName()), false);
+ String methodParameterName = FormDataUtility.getValidMethodParameterName(lowerColName);
+ String propertyName = "m_" + methodParameterName;
+ String colSignature = getColumnSignature(column, hierarchy);
+
+ // property
+ FieldSourceBuilder prop = new FieldSourceBuilder();
+ prop.setElementName(propertyName);
+ prop.setSignature(colSignature);
+ tableBeanBuilder.addBuilder(prop, new CompositeObject(CATEGORY_TYPE_TABLE_COLUMN, 1, i, 0, prop));
+
+ // setter
+ MethodSourceBuilder propSetter = new MethodSourceBuilder(NL);
+ propSetter.setElementName("set" + upperColName);
+ propSetter.addParameter(new MethodParameter(colSignature, methodParameterName));
+ propSetter.setSimpleBody(propertyName + " = " + methodParameterName + ";");
+ tableBeanBuilder.addBuilder(propSetter, new CompositeObject(CATEGORY_TYPE_TABLE_COLUMN, 2, i, 2, propSetter));
+
+ // getter
+ MethodSourceBuilder propGetter = new MethodSourceBuilder(NL);
+ propGetter.setSimpleBody("return " + propertyName + ";");
+ propGetter.setElementName("get" + upperColName);
+ propGetter.setReturnSignature(colSignature);
+ tableBeanBuilder.addBuilder(propGetter, new CompositeObject(CATEGORY_TYPE_TABLE_COLUMN, 2, i, 2, propGetter));
+ }
+ catch (JavaModelException e) {
+ ScoutSdk.logWarning("could not add column '" + column.getFullyQualifiedName() + "' to form data.", e);
+ }
+ }
+
+ // getRows
+ MethodSourceBuilder getRows = addMethodOverride("getRows");
+ getRows.setReturnSignature(tableBeanArraySignature);
+ getRows.setSimpleBody("return (" + tableRowBeanName + "[]) super.getRows();");
+
+ // setRows
+ MethodSourceBuilder setRows = new MethodSourceBuilder(NL);
+ setRows.setElementName("setRows");
+ setRows.addParameter(new MethodParameter(tableBeanArraySignature, "rows"));
+ setRows.setSimpleBody("super.setRows(rows);");
+ addBuilder(setRows, CATEGORY_MEHTOD);
+
+ // rowAt
+ MethodSourceBuilder rowAt = addMethodOverride("rowAt");
+ rowAt.setReturnSignature(tableBeanSignature);
+ rowAt.addParameter(new MethodParameter(Signature.SIG_INT, "idx"));
+ rowAt.setSimpleBody("return (" + tableRowBeanName + ") super.rowAt(idx);");
+
+ // addRow
+ MethodSourceBuilder addRow = addMethodOverride("addRow");
+ addRow.setReturnSignature(tableBeanSignature);
+ addRow.setSimpleBody("return (" + tableRowBeanName + ") super.addRow();");
+
+ // addRowWithRowState
+ MethodSourceBuilder addRowWithRowState = addMethodOverride("addRow");
+ addRowWithRowState.setReturnSignature(tableBeanSignature);
+ addRowWithRowState.addParameter(new MethodParameter(Signature.SIG_INT, "rowState"));
+ addRowWithRowState.setSimpleBody("return (" + tableRowBeanName + ") super.addRow(rowState);");
+
+ // createRow
+ MethodSourceBuilder createRow = addMethodOverride("createRow");
+ createRow.setReturnSignature(tableBeanSignature);
+ createRow.setSimpleBody("return new " + tableRowBeanName + "();");
+
+ // getRowType
+ MethodSourceBuilder getRowType = addMethodOverride("getRowType");
+ getRowType.setReturnSignature(Signature.createTypeSignature(Class.class.getName() + "<? extends " + RuntimeClasses.AbstractTableRowData + ">", true));
+ getRowType.setSimpleBody("return " + tableRowBeanName + ".class;");
+ }
+
+ protected String getTableRowBeanName(IType table) {
+ String tableRowBeanName = table.getElementName();
+ if (iTable.equals(table) || "table".equalsIgnoreCase(tableRowBeanName)) {
+ // use table fields name
+ tableRowBeanName = FormDataUtility.getFieldNameWithoutSuffix(table.getDeclaringType().getElementName());
+ }
+ tableRowBeanName = tableRowBeanName + TABLE_ROW_BEAN_SUFFIX;
+ return tableRowBeanName;
+ }
+
+ /**
+ * Creates, adds and returns a {@link MethodSourceBuilder} with the given name. The {@link Override} annotation
+ * builder is already attached. Note: parametrs, return type and the method body must be set by the caller.
+ *
+ * @param methodName
+ * @return
+ */
+ private MethodSourceBuilder addMethodOverride(String methodName) {
+ MethodSourceBuilder method = new MethodSourceBuilder(NL);
+ method.setElementName(methodName);
+ method.addAnnotation(new AnnotationSourceBuilder(Signature.createTypeSignature(Override.class.getName(), true)));
+ addBuilder(method, CATEGORY_MEHTOD);
+ return method;
+ }
+
+ /**
+ * Computes the given column's type signature that is also the type of the property generated in the table row data.
+ *
+ * @param type
+ * @param columnHierarchy
+ * @return
+ * @throws JavaModelException
+ */
+ private String getColumnSignature(IType type, ITypeHierarchy columnHierarchy) throws JavaModelException {
+ if (type == null || Object.class.getName().equals(type.getFullyQualifiedName())) {
+ return null;
+ }
+ IType superType = columnHierarchy.getSuperclass(type);
+ if (TypeUtility.exists(superType)) {
+ if (TypeUtility.isGenericType(superType)) {
+ String superTypeSig = type.getSuperclassTypeSignature();
+ return SignatureUtility.getResolvedSignature(Signature.getTypeArguments(superTypeSig)[0], type);
+ }
+ else {
+ return getColumnSignature(superType, columnHierarchy);
+ }
+ }
+ else {
+ return null;
+ }
+ }
+
+ /**
+ * Computes the super class signature of the AbstractTableRowData bean created by this builder.
+ *
+ * @param table
+ * @param hierarchy
+ * @return
+ */
+ private String getTableRowDataSuperClassSignature(IType table, ITypeHierarchy hierarchy) {
+ try {
+ IType parentTable = hierarchy.getSuperclass(table);
+ if (TypeUtility.exists(parentTable)) {
+ IType declaringType = parentTable.getDeclaringType();
+ if (TypeUtility.exists(declaringType)) {
+ IType formDataType = ScoutTypeUtility.getFormDataType(declaringType, hierarchy);
+ String parentTableRowBeanName = getTableRowBeanName(parentTable);
+ IType parentTableBeanData = formDataType.getType(parentTableRowBeanName);
+ if (TypeUtility.exists(parentTableBeanData)) {
+ return Signature.createTypeSignature(parentTableBeanData.getTypeQualifiedName(), false);
+ }
+ }
+ }
+ }
+ catch (JavaModelException e) {
+ ScoutSdk.logWarning("error while computing super class signature for [" + table + "]", e);
+ }
+ return Signature.createTypeSignature(RuntimeClasses.AbstractTableRowData, true);
+ }
+}