use of io.jmix.ui.xml.layout.loader.LayoutLoader in project jmix by jmix-framework.
the class ScreensImpl method loadWindowFromXml.
protected <T extends Screen> void loadWindowFromXml(Element element, WindowInfo windowInfo, Window window, T controller, ComponentLoaderContext componentLoaderContext) {
if (windowInfo.getTemplate() != null) {
findMessageGroup(element, windowInfo.getTemplate(), componentLoaderContext);
}
LayoutLoader layoutLoader = applicationContext.getBean(LayoutLoader.class, componentLoaderContext);
ComponentLoader<Window> windowLoader = layoutLoader.createWindowContent(window, element);
windowLoader.loadComponent();
}
use of io.jmix.ui.xml.layout.loader.LayoutLoader in project jmix by jmix-framework.
the class FragmentsImpl method createFragment.
protected <T extends ScreenFragment> T createFragment(FrameOwner parent, WindowInfo windowInfo, ScreenOptions options) {
if (windowInfo.getType() != WindowInfo.Type.FRAGMENT) {
throw new IllegalArgumentException(String.format("Unable to create fragment %s it is a screen: %s", windowInfo.getId(), windowInfo.getControllerClass()));
}
Timer.Sample createSample = Timer.start(meterRegistry);
Fragment fragment = createFragmentInternal();
ScreenFragment controller = fragmentHelper.createController(windowInfo, fragment);
// setup screen and controller
setHostController(controller, parent);
setWindowId(controller, windowInfo.getId());
setFrame(controller, fragment);
setScreenContext(controller, new ScreenContextImpl(windowInfo, options, getScreenContext(parent)));
setScreenData(controller, applicationContext.getBean(ScreenData.class));
FragmentImplementation fragmentImpl = (FragmentImplementation) fragment;
fragmentImpl.setFrameOwner(controller);
fragmentImpl.setId(controller.getId());
createSample.stop(createScreenTimer(meterRegistry, ScreenLifeCycle.CREATE, windowInfo.getId()));
Timer.Sample loadSample = Timer.start(meterRegistry);
Frame parentFrame = getFrame(parent);
// fake parent loader context
ComponentLoaderContext loaderContext = createComponentLoaderContext(options);
FragmentContextImpl frameContext = new FragmentContextImpl(fragment, loaderContext);
frameContext.setManualInitRequired(true);
((FrameImplementation) fragment).setContext(frameContext);
loaderContext.setCurrentFrameId(windowInfo.getId());
loaderContext.setFullFrameId(windowInfo.getId());
loaderContext.setFrame(fragment);
loaderContext.setParent(null);
loaderContext.setScreenData(UiControllerUtils.getScreenData(parent));
// load XML if needed
if (windowInfo.getTemplate() != null) {
ComponentLoaderContext innerContext = createComponentLoaderContext(options);
innerContext.setCurrentFrameId(windowInfo.getId());
innerContext.setFullFrameId(windowInfo.getId());
innerContext.setFrame(fragment);
innerContext.setParent(loaderContext);
LayoutLoader layoutLoader = applicationContext.getBean(LayoutLoader.class, innerContext);
Element rootElement = screenXmlLoader.load(windowInfo.getTemplate(), windowInfo.getId(), emptyMap());
innerContext.setMessageGroup(fragmentHelper.findMessageGroup(rootElement, windowInfo.getTemplate()));
loadAdditionalData(rootElement, innerContext);
ComponentLoader<Fragment> fragmentLoader = layoutLoader.createFragmentContent(fragment, rootElement);
fragmentLoader.loadComponent();
loaderContext.getInjectTasks().addAll(innerContext.getInjectTasks());
loaderContext.getInitTasks().addAll(innerContext.getInitTasks());
loaderContext.getPostInitTasks().addAll(innerContext.getPostInitTasks());
}
loaderContext.addInjectTask(new FragmentLoaderInjectTask(fragment, options, applicationContext));
loaderContext.addInitTask(new FragmentLoaderInitTask(fragment, options, loaderContext, applicationContext));
loadSample.stop(createScreenTimer(meterRegistry, ScreenLifeCycle.LOAD, windowInfo.getId()));
loaderContext.executeInjectTasks();
fragmentImpl.setFrame(parentFrame);
// noinspection unchecked
return (T) controller;
}
use of io.jmix.ui.xml.layout.loader.LayoutLoader in project jmix by jmix-framework.
the class FieldGroupLoader method loadField.
protected FieldGroup.FieldConfig loadField(Element element, Datasource ds, String columnWidth) {
String id = element.attributeValue("id");
String property = element.attributeValue("property");
if (Strings.isNullOrEmpty(id) && Strings.isNullOrEmpty(property)) {
throw new GuiDevelopmentException(String.format("id/property is not defined for field of FieldGroup '%s'. " + "Set id or property attribute.", resultComponent.getId()), context);
}
if (Strings.isNullOrEmpty(property)) {
property = id;
} else if (Strings.isNullOrEmpty(id)) {
id = property;
}
Datasource targetDs = ds;
Datasource datasource = loadDatasource(element);
if (datasource != null) {
targetDs = datasource;
}
CollectionDatasource optionsDs = null;
String optDsName = element.attributeValue("optionsDatasource");
if (StringUtils.isNotBlank(optDsName)) {
LegacyFrame frame = (LegacyFrame) getComponentContext().getFrame().getFrameOwner();
DsContext dsContext = frame.getDsContext();
optionsDs = findDatasourceRecursively(dsContext, optDsName);
if (optionsDs == null) {
throw new GuiDevelopmentException(String.format("Options datasource %s not found for field %s", optDsName, id), context);
}
}
boolean customField = false;
String custom = element.attributeValue("custom");
if (StringUtils.isNotEmpty(custom)) {
customField = Boolean.parseBoolean(custom);
}
if (StringUtils.isNotEmpty(element.attributeValue("generator"))) {
customField = true;
}
List<Element> elements = element.elements();
List<Element> customElements = elements.stream().filter(e -> !("formatter".equals(e.getName()) || "validator".equals(e.getName()))).collect(Collectors.toList());
if (!customElements.isEmpty()) {
if (customElements.size() > 1) {
throw new GuiDevelopmentException(String.format("FieldGroup field %s element cannot contains two or more custom field definitions", id), context);
}
if (customField) {
throw new GuiDevelopmentException(String.format("FieldGroup field %s cannot use both custom/generator attribute and inline component definition", id), context);
}
customField = true;
}
if (!customField && targetDs == null) {
throw new GuiDevelopmentException(String.format("Datasource is not defined for FieldGroup field '%s'. " + "Only custom fields can have no datasource.", property), context);
}
FieldGroup.FieldConfig field = resultComponent.createField(id);
if (property != null) {
field.setProperty(property);
}
if (datasource != null) {
field.setDatasource(datasource);
}
if (optionsDs != null) {
field.setOptionsDatasource(optionsDs);
}
String stylename = element.attributeValue("stylename");
if (StringUtils.isNotEmpty(stylename)) {
field.setStyleName(stylename);
}
MetaPropertyPath metaPropertyPath = null;
if (targetDs != null && property != null) {
MetaClass metaClass = targetDs.getMetaClass();
metaPropertyPath = getMetadataTools().resolveMetaPropertyPathOrNull(targetDs.getMetaClass(), property);
if (metaPropertyPath == null) {
if (!customField) {
throw new GuiDevelopmentException(String.format("Property '%s' is not found in entity '%s'", property, metaClass.getName()), context);
}
}
}
String propertyName = metaPropertyPath != null ? metaPropertyPath.getMetaProperty().getName() : null;
if (metaPropertyPath != null && DynAttrUtils.isDynamicAttributeProperty(propertyName)) {
String attributeCode = DynAttrUtils.getAttributeCodeFromProperty(propertyName);
getDynAttrMetadata().getAttributes(metaPropertyPath.getMetaClass()).stream().filter(attr -> Objects.equals(attributeCode, attr.getCode())).findFirst().ifPresent(attr -> {
field.setCaption(getMessageBundleTools().getLocalizedValue(attr.getNameMsgBundle(), attr.getName()));
field.setDescription(getMessageBundleTools().getLocalizedValue(attr.getDescriptionsMsgBundle(), attr.getDescription()));
});
} else {
loadCaption(field, element);
if (field.getCaption() == null) {
field.setCaption(getDefaultCaption(field, targetDs));
}
}
loadDescription(field, element);
loadContextHelp(field, element);
field.setXmlDescriptor(element);
Formatter formatter = loadFormatter(element);
if (formatter != null) {
field.setFormatter(formatter);
}
String defaultWidth = element.attributeValue("width");
if (StringUtils.isEmpty(defaultWidth)) {
defaultWidth = columnWidth;
}
loadWidth(field, defaultWidth);
if (customField) {
field.setCustom(true);
}
String required = element.attributeValue("required");
if (StringUtils.isNotEmpty(required)) {
field.setRequired(Boolean.parseBoolean(required));
}
String requiredMsg = element.attributeValue("requiredMessage");
if (requiredMsg != null) {
requiredMsg = loadResourceString(requiredMsg);
field.setRequiredMessage(requiredMsg);
}
String tabIndex = element.attributeValue("tabIndex");
if (StringUtils.isNotEmpty(tabIndex)) {
field.setTabIndex(Integer.parseInt(tabIndex));
}
loadInputPrompt(field, element);
if (customElements.size() == 1) {
// load nested component defined as inline
Element customFieldElement = customElements.get(0);
LayoutLoader loader = getLayoutLoader();
ComponentLoader childComponentLoader = loader.createComponent(customFieldElement);
childComponentLoader.loadComponent();
Component customComponent = childComponentLoader.getResultComponent();
String inlineAttachMode = element.attributeValue("inlineAttachMode");
if (StringUtils.isNotEmpty(inlineAttachMode)) {
field.setComponent(customComponent, FieldGroup.FieldAttachMode.valueOf(inlineAttachMode));
} else {
field.setComponent(customComponent);
}
}
return field;
}
use of io.jmix.ui.xml.layout.loader.LayoutLoader in project jmix by jmix-framework.
the class RuntimePropertiesFrameLoader method createComponent.
@Override
public void createComponent() {
String src = element.attributeValue("src");
String screenId = element.attributeValue("id");
if (src == null) {
src = DEFAULT_DESCRIPTOR;
}
String fragmentId = screenId != null ? screenId : src;
FragmentHelper fragmentHelper = getFragmentHelper();
FrameHelper frameHelper = getFrameHelper();
WindowInfo windowInfo = frameHelper.createFakeWindowInfo(src, fragmentId);
UiComponents uiComponents = applicationContext.getBean(UiComponents.class);
Fragment fragment = uiComponents.create(Fragment.NAME);
ScreenFragment controller = fragmentHelper.createController(windowInfo, fragment);
// setup screen and controller
ComponentLoaderContext parentContext = (ComponentLoaderContext) getContext();
FrameOwner hostController = parentContext.getFrame().getFrameOwner();
// setup screen and controller
setHostController(controller, hostController);
setWindowId(controller, windowInfo.getId());
setFrame(controller, fragment);
setScreenContext(controller, new ScreenContextImpl(windowInfo, parentContext.getOptions(), getScreenContext(hostController)));
setScreenData(controller, applicationContext.getBean(ScreenData.class));
FragmentImplementation fragmentImpl = (FragmentImplementation) fragment;
fragmentImpl.setFrameOwner(controller);
fragmentImpl.setId(fragmentId);
FragmentContextImpl frameContext = new FragmentContextImpl(fragment, innerContext);
((FrameImplementation) fragment).setContext(frameContext);
if (windowInfo.getTemplate() != null) {
String frameId = fragmentId;
if (parentContext.getFullFrameId() != null) {
frameId = parentContext.getFullFrameId() + "." + frameId;
}
innerContext = new ComponentLoaderContext(getContext().getOptions());
innerContext.setMessageGroup(fragmentHelper.getMessageGroup(windowInfo.getTemplate()));
innerContext.setCurrentFrameId(fragmentId);
innerContext.setFullFrameId(frameId);
innerContext.setFrame(fragment);
innerContext.setParent(parentContext);
LayoutLoader layoutLoader = getLayoutLoader(innerContext);
ScreenXmlLoader screenXmlLoader = applicationContext.getBean(ScreenXmlLoader.class);
Element rootElement = screenXmlLoader.load(windowInfo.getTemplate(), windowInfo.getId(), getContext().getParams());
String messagesPack = rootElement.attributeValue("messagesPack");
if (messagesPack != null) {
innerContext.setMessageGroup(messagesPack);
}
this.fragmentLoader = layoutLoader.createFragmentContent(fragment, rootElement);
}
this.resultComponent = fragment;
}
Aggregations