Skip to content
This repository has been archived by the owner on Mar 31, 2022. It is now read-only.

Commit

Permalink
Unable to inject facet's actions to screen controllers #440
Browse files Browse the repository at this point in the history
  • Loading branch information
Flaurite committed Jul 30, 2021
1 parent 35f9c9f commit 215ec03
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,7 @@
import io.jmix.core.DevelopmentException;
import io.jmix.ui.WindowParam;
import io.jmix.ui.action.Action;
import io.jmix.ui.component.Component;
import io.jmix.ui.component.ComponentsHelper;
import io.jmix.ui.component.Facet;
import io.jmix.ui.component.Fragment;
import io.jmix.ui.component.Frame;
import io.jmix.ui.component.FrameContext;
import io.jmix.ui.component.HasComponents;
import io.jmix.ui.component.HasSubParts;
import io.jmix.ui.component.*;
import io.jmix.ui.download.Downloader;
import io.jmix.ui.model.DataContext;
import io.jmix.ui.model.DataLoader;
Expand All @@ -46,6 +39,7 @@
import io.jmix.ui.sys.event.UiEventListenerMethodAdapter;
import io.jmix.ui.theme.ThemeConstants;
import io.jmix.ui.theme.ThemeConstantsManager;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -70,6 +64,7 @@
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
Expand Down Expand Up @@ -668,6 +663,46 @@ protected Object getInjectedInstance(Class<?> type, String name, InjectElement i
genericType = ((ParameterizedType) genericType).getRawType();
}
return applicationContext.getBeanProvider((Class<?>) genericType);
} else if (ActionsAwareDialogFacet.DialogAction.class.isAssignableFrom(type)) {
// facet's action

Facet facet;
String actionId;

String[] path = ValuePathHelper.parse(name);
if (path.length == 2) {
facet = frame.getFacet(path[0]);
actionId = path[1];
} else {
String prefix = ValuePathHelper.pathPrefix(path, 2);
Component component = frame.getComponent(prefix);
if (component == null) {
return null;
}
if (!(component instanceof Fragment)) {
throw new UnsupportedOperationException(
String.format("Unable to inject dialog action with id '%s'. Component '%s' is not a fragment",
name, prefix)
);
}
actionId = path[path.length - 1];
facet = ((Fragment) component).getFacet(path[path.length - 2]);
}

if (!(facet instanceof ActionsAwareDialogFacet)) {
return null;
}

//noinspection unchecked
Collection<ActionsAwareDialogFacet.DialogAction<Facet>> actions =
((ActionsAwareDialogFacet<Facet>) facet).getActions();

if (CollectionUtils.isNotEmpty(actions)) {
return actions.stream()
.filter(action -> action.getId().equals(actionId))
.findFirst()
.orElse(null);
}
} else {
Object instance;
// Try to find a Spring bean
Expand Down
6 changes: 5 additions & 1 deletion ui/src/main/java/io/jmix/ui/sys/ValuePathHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ public static String pathSuffix(String[] elements) {
}

public static String pathPrefix(String[] elements) {
String[] subPath = ArrayUtils.subarray(elements, 0, elements.length - 1);
return pathPrefix(elements, 1);
}

public static String pathPrefix(String[] elements, int beforeLastElements) {
String[] subPath = ArrayUtils.subarray(elements, 0, elements.length - beforeLastElements);
return ValuePathHelper.format(subPath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.ApplicationContext
import org.springframework.test.context.ContextConfiguration
import test_support.UiTestConfiguration
import ui_controller_dependency_injector.screen.AutowireFacetDialogActionTestScreen
import ui_controller_dependency_injector.screen.AutowireToFieldsTestScreen
import ui_controller_dependency_injector.screen.AutowireToSettersTestScreen
import ui_controller_dependency_injector.screen.WindowParamTestScreen
Expand Down Expand Up @@ -113,4 +114,23 @@ class UiControllerDependencyInjectorTest extends ScreenSpecification {
screen.optionalParam == null
screen.namedParam == 'named'
}

def "Dependency injector supports ActionsAwareDialogFacet DialogAction"() {
showTestMainScreen()

when: "Show screen that contains facets and fragment with facets"
def screen = (AutowireFacetDialogActionTestScreen) screens.create(AutowireFacetDialogActionTestScreen)
screen.show()

then: "Actions should be injected to the controller of the screen and to the fragment"

screen.okInputDialog != null
screen.okOptionDialog != null

screen.okFragmentInputDialog != null
screen.okFragmentOptionDialog != null

screen.testFragment.okFragmentInputDialog != null
screen.testFragment.okFragmentOptionDialog != null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2021 Haulmont.
*
* 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 ui_controller_dependency_injector.screen;

import io.jmix.ui.component.ActionsAwareDialogFacet;
import io.jmix.ui.screen.ScreenFragment;
import io.jmix.ui.screen.UiController;
import io.jmix.ui.screen.UiDescriptor;

import javax.inject.Named;

@UiController
@UiDescriptor("autowire-facet-dialog-action-test-fragment.xml")
public class AutowireFacetDialogActionTestFragment extends ScreenFragment {

@Named("fragmentInputDialog.okAction")
public ActionsAwareDialogFacet.DialogAction okFragmentInputDialog;
@Named("fragmentOptionDialog.okAction")
public ActionsAwareDialogFacet.DialogAction okFragmentOptionDialog;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2021 Haulmont.
*
* 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 ui_controller_dependency_injector.screen;

import io.jmix.ui.component.ActionsAwareDialogFacet;
import io.jmix.ui.screen.Screen;
import io.jmix.ui.screen.UiController;
import io.jmix.ui.screen.UiDescriptor;
import org.springframework.beans.factory.annotation.Autowired;

import javax.inject.Named;

@UiController
@UiDescriptor("autowire-facet-dialog-action-test-screen.xml")
public class AutowireFacetDialogActionTestScreen extends Screen {

@Named("inputDialog.okAction")
public ActionsAwareDialogFacet.DialogAction okInputDialog;
@Named("optionDialog.okAction")
public ActionsAwareDialogFacet.DialogAction okOptionDialog;

@Named("testFragment.fragmentInputDialog.okAction")
public ActionsAwareDialogFacet.DialogAction okFragmentInputDialog;
@Named("testFragment.fragmentOptionDialog.okAction")
public ActionsAwareDialogFacet.DialogAction okFragmentOptionDialog;

@Autowired
public AutowireFacetDialogActionTestFragment testFragment;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!--
~ Copyright 2021 Haulmont.
~
~ 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.
-->

<fragment xmlns="http://jmix.io/schema/ui/fragment">
<facets>
<inputDialog id="fragmentInputDialog">
<parameters>
<stringParameter id="name"/>
</parameters>
<actions>
<action id="okAction"/>
</actions>
</inputDialog>
<optionDialog id="fragmentOptionDialog">
<actions>
<action id="okAction"/>
</actions>
</optionDialog>
</facets>
<layout>
</layout>
</fragment>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!--
~ Copyright 2021 Haulmont.
~
~ 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.
-->

<window xmlns="http://jmix.io/schema/ui/window">
<facets>
<inputDialog id="inputDialog">
<parameters>
<stringParameter id="name"/>
</parameters>
<actions>
<action id="okAction"/>
</actions>
</inputDialog>
<optionDialog id="optionDialog">
<actions>
<action id="okAction"/>
</actions>
</optionDialog>
</facets>
<layout>
<fragment id="testFragment" screen="AutowireFacetDialogActionTestFragment"/>
</layout>
</window>

0 comments on commit 215ec03

Please sign in to comment.