This one is a little tricky, and definitely non-obvious. But possible!
You're right, you should add a foreign key to the Store back to Product. In order for the admin to work properly this is often the case (adding the bidrectional relationship). So, I'm going to assume you have a Store that looks something like this:
Code: Select all
@Entity
@AdminPresentationClass(populateToOneFields=PopulateToOneFieldsEnum.TRUE)
public class StoreImpl implements Serializable {
@ManyToOne(targetEntity = ProductImpl.class, optional=false)
@JoinColumn(name="PRODUCT_ID")
@AdminPresentation(friendlyName="Default Product", excluded=true, fieldType=SupportedFieldType.FOREIGN_KEY)
protected Product defaultProduct;
}
What this will do on the admin is create a form item with a '...' button that has the name "Default Product" when creating a new Store. Of course, this button isn't hooked up to anything yet and you'll get a GWT exception if you try to click on it.
Let's now put a FormItemCallback on the Store datasource and set up the ProductSearchDataSource:
in StorePresenter.java:
Code: Select all
public class StorePresenter extends DynamicEntityPresenter implements Instantiable {
@Override
public void setup()
getPresenterSequenceSetupManager().addOrReplaceItem(new PresenterSetupItem("storeDS", new StoreDataSourceFactory(), new AsyncCallbackAdapter() {
public void onSetupSuccess(DataSource top) {
setupDisplayItems(top);
((ListGridDataSource) top).setupGridFields(new String[]{"storeField1", "storeField2", "storeField3"}, new Boolean[]{false, true, true});
}
}));
getPresenterSequenceSetupManager().addOrReplaceItem(new PresenterSetupItem("productSearchDS", new ProductDataSourceFactory(), new OperationTypes(OperationType.ENTITY, OperationType.ENTITY, OperationType.JOINSTRUCTURE, OperationType.ENTITY, OperationType.ENTITY), new Object[]{}, new AsyncCallbackAdapter() {
public void onSetupSuccess(DataSource result) {
ListGridDataSource productSearchDataSource = (ListGridDataSource) result;
productSearchDataSource.resetPermanentFieldVisibility(
"name",
"description"
);
EntitySearchDialog productSearchView = new EntitySearchDialog(productSearchDataSource, true);
getPresenterSequenceSetupManager().getDataSource("storeDS").getFormItemCallbackHandlerManager().addSearchFormItemCallback(
"defaultProduct",
productSearchView,
"Search for a Product",
getDisplay().getDynamicFormDisplay()
);
}
}));
And you're done. I think your original question was about the DataSourceFactory. In this example, I called it ProductDataSourceFactory() which is just a simple call to pull back all of the Products:
Code: Select all
public class ProductDataSourceFactory implements DataSourceFactory {
public static ListGridDataSource dataSource = null;
public void createDataSource(String name, OperationTypes operationTypes, Object[] additionalItems, AsyncCallback<DataSource> cb) {
if (dataSource == null) {
operationTypes = new OperationTypes(OperationType.ENTITY, OperationType.ENTITY, OperationType.ENTITY, OperationType.ENTITY, OperationType.ENTITY);
PersistencePerspective persistencePerspective = new PersistencePerspective(operationTypes, new String[]{}, new ForeignKey[]{});
DataSourceModule[] modules = new DataSourceModule[]{
new BasicClientEntityModule(CeilingEntities.PRODUCT, persistencePerspective, AppServices.DYNAMIC_ENTITY)
};
dataSource = new ListGridDataSource(name, persistencePerspective, AppServices.DYNAMIC_ENTITY, modules);
dataSource.buildFields(null, false, cb);
} else {
if (cb != null) {
cb.onSuccess(dataSource);
}
}
}
}
One caveat. I don't think this is necessary because in the annotation for defaultProduct, but you might have to do this in StoreDataSourceFactory:
Code: Select all
public class StoreDataSourceFactory implements DataSourceFactory {
public static ListGridDataSource dataSource = null;
public void createDataSource(String name, OperationTypes operationTypes, Object[] additionalItems, AsyncCallback<DataSource> cb) {
if (dataSource == null) {
operationTypes = new OperationTypes(OperationType.ENTITY, OperationType.ENTITY, OperationType.ENTITY, OperationType.ENTITY, OperationType.ENTITY);
PersistencePerspective persistencePerspective = new PersistencePerspective(operationTypes, new String[]{}, new ForeignKey[]{new ForeignKey("defaultProduct", EntityImplementations.PRODUCT, null)});
DataSourceModule[] modules = new DataSourceModule[]{
new BasicClientEntityModule(MyCompanyCeilingEntities.STORE, persistencePerspective, AppServices.DYNAMIC_ENTITY)
};
dataSource = new ListGridDataSource(name, persistencePerspective, AppServices.DYNAMIC_ENTITY, modules);
dataSource.buildFields(null, false, cb);
} else {
if (cb != null) {
cb.onSuccess(dataSource);
}
}
}
}
But like I said, I'm not sure if that part is necessary.
Hopefully that helps. Let me know if you have any questions about any of that; it's kind of a long response.