Parsley autowiring not working - apache-flex

I'm starting with Parsley and cannot manage to make the autowire working. My configuration is based on flex 4.5 and parsley 3.0.0.
My application contains the folowing bootrap :
<fx:Declarations>
<parsley:ViewSettings autowireComponents="true"/>
<parsley:ContextBuilder config="{SimulateurConfig}" />
<s:TraceTarget
includeCategory="true"
includeLevel="true"
includeTime="true"
level="{LogEventLevel.DEBUG}"
>
<s:filters>
<fx:String>org.spicefactory.parsley.*</fx:String>
</s:filters>
</s:TraceTarget>
</fx:Declarations>
The configuration is quite simple :
<fx:Declarations>
<View type="com.coach.ui.PanelAFinancer"/>
<Object type="com.coach.domain.AFinancer" />
</fx:Declarations>
And my Panel contains :
<fx:Script><![CDATA[
import com.coach.domain.AFinancer;
[Bindable] [Inject]
public var model:AFinancer;
]]></fx:Script>
<s:Label text="Model injected? { model != null }"/>
I think I did everything right but the model is not injected in my view. The trace indicates :
[trace] 12:49:12.186 [INFO] org.spicefactory.parsley.core.state.manager.impl.DefaultGlobalDomainManager Using new ApplicationDomain for key [object _Flex_simulateur_mx_managers_SystemManager]
[trace] 12:49:12.218 [INFO] org.spicefactory.parsley.core.view.impl.DefaultViewManager Add view root: Flex_simulateur0/Flex_simulateur
[trace] 12:49:12.218 [INFO] org.spicefactory.parsley.core.bootstrap.impl.DefaultBootstrapManager Creating Context [Context(FlexConfig{SimulateurConfig})] without parent
[trace] 12:49:12.296 [INFO] org.spicefactory.parsley.core.lifecycle.impl.DefaultManagedObjectHandler Configure managed object with [ObjectDefinition(type = com.coach.domain::AFinancer, id = _SimulateurConfig_MxmlRootObjectTag1)] and 0 processor(s)
No sign of view processing.
If I add the «manual configuration» in the panel :
<fx:Declarations>
<sf:Configure/>
</fx:Declarations>
The injection works:
[trace] 12:56:04.983 [INFO] org.spicefactory.parsley.core.state.manager.impl.DefaultGlobalDomainManager Using new ApplicationDomain for key [object _Flex_simulateur_mx_managers_SystemManager]
[trace] 12:56:05.015 [INFO] org.spicefactory.parsley.core.view.impl.DefaultViewManager Add view root: Flex_simulateur0/Flex_simulateur
[trace] 12:56:05.030 [INFO] org.spicefactory.parsley.core.bootstrap.impl.DefaultBootstrapManager Creating Context [Context(FlexConfig{SimulateurConfig})] without parent
[trace] 12:56:05.124 [INFO] org.spicefactory.parsley.core.lifecycle.impl.DefaultManagedObjectHandler Configure managed object with [ObjectDefinition(type = com.coach.domain::AFinancer, id = _SimulateurConfig_MxmlRootObjectTag1)] and 0 processor(s)
[trace] 12:56:05.140 [DEBUG] org.spicefactory.parsley.core.view.handler.ViewConfigurationHandler Process view 'Flex_simulateur0.ApplicationSkin3._ApplicationSkin_Group1.contentGroup.viewRoot.PanelAFinancer7' with [Context(FlexConfig{SimulateurConfig})]
[trace] 12:56:05.155 [INFO] org.spicefactory.parsley.core.lifecycle.impl.DefaultManagedObjectHandler Configure managed object with [ObjectDefinition(type = com.coach.ui::PanelAFinancer, id = _SimulateurConfig_MxmlViewTag1)] and 1 processor(s)
[trace] 12:56:05.155 [DEBUG] org.spicefactory.parsley.core.lifecycle.impl.DefaultManagedObjectHandler Applying [Property(name=[Property model in class com.coach.ui::PanelAFinancer],value={ImplicitTypeReference(type=undefined)})] to managed object with [ObjectDefinition(type = com.coach.ui::PanelAFinancer, id = _SimulateurConfig_MxmlViewTag1)]
[trace] 12:56:05.171 [DEBUG] org.spicefactory.parsley.core.view.processor.DefaultViewProcessor Add view 'Flex_simulateur0.ApplicationSkin3._ApplicationSkin_Group1.contentGroup.viewRoot.PanelAFinancer7' to [Context(FlexConfig{SimulateurConfig})]
The workaround is quite heavy as it requires adding in all my views the proprietary tags.
Any idea of what is wrong with my configuration?

I would recommend that you use another solution. When you configure (or wire) a view, Parsley needs to reflect the class and iterate through all properties to find the injection points. This is costly and time consuming. It might be fine for only a few wired views, but normally that is not the case since if you're using Flex and Parsley, there's a good chance you'll have a lot of views.
The better approach is to create all models, presenters, services, etc. in the parsley config, excluding all Views. In the views, you'd only have to use the FastInject tag as such:
<fx:Declarations>
<spicefactory:FastInject property="model" type="{AFinancer}" />
</fx:Declarations>
<fx:Script><![CDATA[
import com.coach.domain.AFinancer;
[Bindable]
public var model:AFinancer;
]]></fx:Script>
This is a much better approach since reflection isn't needed. The only "issue" is that you cannot use Parsley metadata in your views, which is better for separating business concerns from the view. This also helps you reuse presenters throughout your application and help out with testing of said presenters.

Related

How to use js:DataGrid on Apache Royale ? Issue with Language.synthType

I have an issue using this code, I don't know what Language.synthType is...
Used SDK is 0.9.6
<j:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:local="*"
xmlns:models="models.*"
xmlns:js="library://ns.apache.org/royale/basic"
xmlns:j="library://ns.apache.org/royale/jewel"
xmlns:binding="org.apache.royale.binding.*"
applicationComplete="ev_applicationComplete()">
<fx:Script>
<![CDATA[
import org.apache.royale.collections.ArrayList;
private function ev_applicationComplete():void {
dg.dataProvider = new ArrayList( [
{label:'Apple',code:'1'},
{label:'Nuts',code:'2'}
]);
}
]]>
</fx:Script>
<js:valuesImpl>
<js:SimpleCSSValuesImpl />
</js:valuesImpl>
<js:initialView >
<j:View>
<j:beads>
<js:ContainerDataBinding/>
</j:beads>
<js:DataGrid id="dg" width="600" height="300">
<js:columns>
<js:DataGridColumn label="Label" dataField="label" columnWidth="300" />
<js:DataGridColumn label="Code" dataField="code" columnWidth="300"/>
</js:columns>
</js:DataGrid>
</j:View>
</js:initialView>
</j:Application>
When running code this issue is throw
EventDispatcher.js:74 Uncaught TypeError: org.apache.royale.utils.Language.synthType is not a function
at org.apache.royale.html.beads.DataGridView.handleInitComplete (DataGridView.js:88)
at org.apache.royale.html.DataGrid.goog.events.EventTarget.fireListeners (eventtarget.js:284)
at Function.goog.events.EventTarget.dispatchEventInternal_ (eventtarget.js:382)
at org.apache.royale.html.DataGrid.goog.events.EventTarget.dispatchEvent (eventtarget.js:196)
at org.apache.royale.html.DataGrid.org.apache.royale.events.EventDispatcher.dispatchEvent (EventDispatcher.js:71)
at org.apache.royale.html.DataGrid.org.apache.royale.core.HTMLElementWrapper.dispatchEvent (HTMLElementWrapper.js:245)
at org.apache.royale.html.DataGrid.addedToParent (DataGrid.js:58)
at org.apache.royale.jewel.View.org.apache.royale.core.UIBase.addElement (UIBase.js:414)
at org.apache.royale.jewel.View.org.apache.royale.core.GroupBase.addElement (GroupBase.js:165)
at Function.org.apache.royale.utils.MXMLDataInterpreter.org_apache_royale_utils_MXMLDataInterpreter_initializeStrandBasedObject (MXMLDataInterpreter.js:236)
That Language.synthType function supports some specific cases when using int, uint, and Class in a very minimal way for typechecking and basic instantiations when held as Class variables ( e.g. var intClass:Class = int; <- you can now use intClass as expected to create an int).
In this specific case it is being used for some ' as Class' type checks, which we can actually optimize out in future builds (because it will be sufficient to do non-null checks in the related site in the DataGridView code - this is all just additional explanation in case you are interested, don't worry about that detail).
So I can understand where the problem is, but I don't understand why your copy of org.apache.royale.utils.Language is missing that function. Is there any chance that you are using an older version of the Language library mixed with the latest 0.9.6 SDK? Or maybe you are using a library that was compiled with an older version of the SDK. I suggest you double check with a 'clean' build if you did not do that already.
If you check in a debug build output, can you confirm that the following is true in your javascript console:
typeof org.apache.royale.utils.Language.synthType == 'function'
If you don't see that, then there must be some conflict between your library versions I think, perhaps an older version of the Language library being used somewhere... If you can provide more details maybe I can help.

Failed to start quarkus: java.lang.ArrayIndexOutOfBoundsException: 1

Quarkus application (0.19.1), created from QuarkEE artifact fails to start with:
[io.qua.dev.DevModeMain] Failed to start quarkus: java.lang.ExceptionInInitializerError ..
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
at io.quarkus.hibernate.validator.runtime.HibernateValidatorRecorder
EDIT
I've opened a ticket for it:
https://github.com/quarkusio/quarkus/issues/3284
Root cause was a bean validation constraint javax.validation.constraints.NotNull on the static factory method of the enum class. Simplified example:
public enum Gender {
MALE,
FEMALE;
public static Gender fromCode(#NotNull String code) {
return Gender.valueOf(code);
}
}
and having this dependency in your pom:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
Confusing thing is that static factory methods on simple POJO class works.
Note
I'm aware that validation of static methods is not supported by the Bean Validation specification. It is just a hint for IDE.
Java EE 8 Validating Constructors and Methods: Bean Validation constraints may be placed on the parameters of nonstatic methods and constructors and on the return values of nonstatic methods. Static methods and constructors will not be validated.

Struts 1.2.9 to spring MVC migration - Handling Scope of ActionForms

We are migrating a Struts 1.2.9 application to Spring MVC.
We are stuck on one point of scope of ActionForm defined to be "session". By default these are on "request" scope and understand on migrating to Spring, we can reuse these as Model Objects that are set in "request" scope by default.
But am lost on how to handle the "session" scope. Kindly advise.
struts-config.xml
<action path="/editSvc" scope="session"
type="com.xyz.myapp.actions.SvcCodeEditAction" name="svcCodeForm"
validate="false" parameter="reqCode">
<forward name="success" path="/WEB-INF/jsp/svccode_edit.jsp" />
</action>
Action Class
//Code in com.xyz.myapp.actions.SvcCodeEditAction
if (request.equals(mapping.getScope())) {
request.setAttribute(mapping.getAttribute(), form);
} else {
setSessionAttribute(session,mapping.getAttribute(), form);
}
You could get the mostly same functionality by using Spring #Scope("session") annotation above the bean class declaration.
It's well explained in reference guide to spring 3.0 version :
https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch04s04.html
In general, if you add a spring-webmvc and spring-web to your project you could use
#Bean
#Scope("session")
public SomeBean someBean() {
return new SomeBean();
}
Or, if you prefer to use xml instead of java config you could go with smth simmilar to this:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
Also there is a good tutorial about it:
http://www.baeldung.com/spring-bean-scopes
Then if you add the bean to the model, it will automatically set-up in session if the bean has #SessionScope or #Scope("session") or whenever else bean scope declaration. By default beans would be added to the request scope.

Spring Data Rest: Entity serialization with LAZY object cause JsonMappingException

I'm getting the following Exception with a Spring Data Rest project:
com.fasterxml.jackson.databind.JsonMappingException:
No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer
(to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) )
(through reference chain: org.springframework.data.rest.webmvc.json.["content"]->test.spring.data.rest.xml.entities.Author_$$_jvstb93_1["handler"])
Certainly, I have some entities that have the fetch configuration = FetchType.LAZY.
I followed many instructions and links, but I still have this exception.
What I have already tried to do (with NO effetcs):
add #EnableHypermediaSupport(type = HypermediaType.HAL) in a config class that extends RepositoryRestMvcConfiguration
#Override configureJacksonObjectMapper in the same class, with also using Jackson2DatatypeHelper.configureObjectMapper():
#Override
protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
Jackson2DatatypeHelper.configureObjectMapper(objectMapper);
}
add a "org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter" filter in the web.xml
create a custom class that extends ObjectMapper, with this constructor:
public HibernateAwareObjectMapper() {
Hibernate5Module hm = new Hibernate5Module();
registerModule(hm);
}
and this config:
<mvc:annotation-driven>
<mvc:message-converters>
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="test.spring.data.rest.xml.config.HibernateAwareObjectMapper" />
</property>
</bean>
</mvc:message-converters>
No one of the actions above has solved the problem!
How to (definitely) solve this problem?
Thanks.
I have found the solution to this annoying problem.
For every repository of the Spring Data Rest application it has to be defined a custom #Projection; in the projection there will be the necessaries fields.
Pay attention that if there are cycylc references between two entities, the corrispective methods of the projections have to be annotated with #JsonBackReference annotation (for #ManyToOne annotated fields) and with #JsonManagedReference annotation (for #OneToMany annotated fields), otherwise there will be a JSON loop in the JSON serialization.
In every #Repository annotation (or #RepositoryRestResource annotation) it has to be marked the excerptProjection property, with the custom projection.
With this management, there is no need of any other configuration, and the exception for Lazy objects finally is vanished.

Microsoft Unity - Is it possible to change the registered type at runtime?

I am currently using Unity with MOQ to do my unit testing for WCF. In the application's code, I have the following:
private void MyMethod()
{
.....
.....
_proxy = new UnityContainer().LoadConfiguration().Resolve<IMyInterface>();
.....
}
In the application's app.config, I have the following:
<container>
<register type="IMyInterface" mapTo="MyActualObject" />
</container>
In the unit test's app.config, I replace that with my mock object implementation of the proxy.
<container>
<register type="IMyInterface" mapTo="MyMockObject" />
</container>
That is all working fine. But what I would like to do further is for certain tests, I would like to replace MyMockObject with a different mock object implementation.
Is it possible to change the registered type at runtime? I have tried modifying the application config during runtime but it fails to detect the change.
Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var section = (UnityConfigurationSection)appConfig.GetSection("unity");
section.Containers[0].Registrations[0].MapToName = "AnotherMockObject";
appConfig.Save();
Thanks!!
Yes its possible.
You can configure Unity as many times as you want. If there's a conflict the most recent definition wins.
In your case if you want to make a runtime change, use the fluent API instead of the config file. Try something like this:
IUnityContainer container = new UnityContainer();
container.LoadConfiguration();
container.RegisterType<IMyInterface, AnotherMockObject>();
// use AnotherMockObject
_proxy = Resolve<IMyInterface>();
The documentation for Registering Types and Type Mappings

Resources