I have an input xml, which i need to parse and bind using JibX.
We make use of a value in a specific node() of our xml to determine the type of child class that has to be initialized.
sample.xml
<MainClass>
<TypeCode>ChildClassType</TypeCode>
<!--Optional:-->
<ChildClassOne_Attribute1></ChildClassOne_Attribute1>
<!--Optional:-->
<ChildClassOne_Attribute2></ChildClassOne_Attribute2>
<!--Optional:-->
<ChildClassTwo_Attribute1></ChildClassTwo_Attribute1>
<!--Optional:-->
<ChildClassTwo_Attribute2></ChildClassTwo_Attribute2>
<!--Optional:-->
<ChildClassThree_Attribute></ChildClassThree_Attribute>
</MainClass>
Is is possible in JibX to parse the above xml and initialize one of the three classes - ChildClassOne, ChildClassTwo, ChildClassThree, based on the 'TypeCode'.
My end result should look like,
Class MainClass{
String TypeCode
}
If my TypeCode is "TypeOne" I need "ChildClassOne" to be initialized
Class ChildClassOne extends MainClass{
ChildClassOne_Attribute1;
ChildClassOne_Attribute2;
}
If my TypeCode is "TypeTwo" I need "ChildClassTwo" to be initialized
Class ChildClassTwo extends MainClass{
ChildClassTwo_Attribute1;
ChildClassTwo_Attribute2;
}
If my TypeCode is "TypeThree" I need "ChildClassThree" to be initialized
Class ChildClassThree extends MainClass{
ChildClassThree_Attribute;
}
Is this possible in JibX or am i asking too much??
Thanks in advance
Praveen
Related
Let's suppose I have following structure:
1) Managed Bean:
#ViewScoped
#ManagedBean
public class TestBean {
private Test test;
//getters/setters
}
2) Test class:
public class Test {
private String attribute;
//gets/sets
}
3) XHTML
<p:inputText id="test" value="#{testBean.test.atribute}" />
Now, I know there is a way to find and get component instance:
UIComponent c = view.findComponent(s);
From UIComponent, how do I get the type bound to component?
What I need is to get full qualified class name from what is set as "value" attribute in component. Something like: package.Test.attribute.
UIComponent offers getValueExpression("attributeName")
sample :
UIViewRoot viewRoot = Faces.getViewRoot();
UIComponent component= viewRoot.findComponent("x");
ValueExpression value = component.getValueExpression("value");
Class<?> expectedType = value.getType(Faces.getELContext());
NB:Faces here is from Omnifaces, which is a "Collection of utility methods for the JSF API that are mainly shortcuts for obtaining stuff from the thread local FacesContext. "
excepts from getType() javadoc
public abstract Class getType(ELContext context) Evaluates the
expression relative to the provided context, and returns the most
general type that is acceptable for an object to be passed as the
value parameter in a future call to the setValue(javax.el.ELContext. java.lang.Object) method. This is not always the same as
getValue().getClass(). For example, in the case of an expression that
references an array element, the getType method will return the
element type of the array, which might be a superclass of the type of
the actual element that is currently in the specified array element.
For MethodExpression read this.
I have a faces-config.xml file with some resource bundles declared, like this:
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>de</supported-locale>
<supported-locale>es</supported-locale>
<supported-locale>pt</supported-locale>
<supported-locale>zh</supported-locale>
</locale-config>
<resource-bundle>
<base-name>messages.Messages</base-name>
<var>bundle</var>
</resource-bundle>
<resource-bundle>
<base-name>countries.Countries</base-name>
<var>countryBundle</var>
</resource-bundle>
</application>
</faces-config>
These resource bundles are registered and can be used in any .xhtml file, but is there any way to register these resource bundles programmatically? I mean by the use of dynamic code instead of a xml declaration.
Here's a simplified version of what I'm doing using CDI:
#ApplicationScoped
public class BundleProducer {
#Produce #RequestScoped #Named
public ResourceBundle getMsgBundle() {
Locale userLocale = Faces.getLocale();
return ResourceBundle.getBundle("messages", userLocale);
}
}
Note the use of omnifaces' getLocale() to avoid a ton of boilerplace code (for a less sane version, you can substitute FacesContext.getCurrentInstance().getViewRoot().getLocale() like in the tutorial you linked to).
This will cause the CDI framework to call getMsgBundle once each request if it needs to access to msgBundle thanks to the #Named annotation. In this simple case, I'm relying on the ResourceBundle internal caching and lookup mechanisms to produce my bundle efficiently. You can execute any logic you like here (eg, load stuff from the enclosing BundleProducer) as long as you return a ResourceBundle from the method (you're not allowed to return null).
Repeat as you like with more methods producing different bundles.
Not sure if I got what you were after, so just comment if you need more clarification.
For easier handling of FacesMessage stuff, I'd recommend having a look at omnifaces' Messages utility class. I use something like this to be able to optionally give bundle keys as message strings:
#Singleton
#Startup
public class MessageResolverInit {
#PostConstruct
public void initMessageResolver() {
Messages.setResolver(new Messages.Resolver() {
#Override
public String getMessage(String message, Object... params) {
Locale userLocale = Faces.getLocale();
ResourceBundle b = ResourceBundle.getBundle("msgs", userLocale);
if (b.containsKey(message)) {
return MessageFormat.format(b.getString(message), params);
}
return message;
}
});
}
Note that I use b as a variable name only for demo purposes. Usage goes like this:
Messages.addGlobalError("my_msg_key", param1);
Messages.addGlobalInfo("I'm a standalone message");
Here is the answer from Oracle documentation: Using FacesMessage to Create a Message
I have just take a look at the 3º tutorial from dart, creating the rating component. I was wondering if there is same method which is called when stringifying an object, something similar to Java's toString.
For example:
MyClass myObject = new MyClass();
System.out.println(myObject);
Will call MyClass.toString() if overwriten, else will call it's parent until java.lang.Object is reached giving a default toString.
I find kind ugly (completely subjective) doing:
<span ng-repeat="star in cmp.stars" > {{star.toString()}} </span>
I would rather do:
<span ng-repeat="star in cmp.stars" > {{star}} </span>
And give the implementation of how I want it to display at an averwritten method. Is this possible?
If you have something like this:
class MyClass {
String data;
MyClass(this.data);
#override
String toString() {
return data;
}
}
MyClass myObject = new MyClass("someData");
print(myObject); // outputs "someData", not 'Instance of MyClass'
I think this might be what you are looking for.
Yes it works like this for print, String interpolation or Angular mustaches.
By overriding the String toString() method on your object the displayed value will be the result of this toString() call. If there's no toString() defined in the class hierarchy the toString() of Object will be called (which will return Instance of 'MyClass' for class MyClass{}).
You may be interesting look how Rating component was implemented in Angular Dart UI project. Check this out.
Sergey.
I am attempting to migrate from Spring to Guice for dependency injection. Here is a sample snippet from a Spring xml config:
<bean id="connectionFactory" class="org.somethirdparty.MyConnectionFactory">
<property name="connectionUrl" value="${urls.connectionUrl}"/>
<property name="ackMode" value="unordered"/>
<property name="timeout" ref="timeoutBean"/>
</bean>
<bean id="timeoutBean" class="java.lang.Integer">
<constructor-arg value="10000"/>
</bean>
I am struggling with figuring out how to parameterize MyConnectionFactory with Google Guice. I cannot annotate the constructor or methods of 'MyConnectionFactory' as this is a class provided by a 3rd party library.
After reading the Guice FAQ it seems to me the only option is to make a Factory for the Factory? That seems silly to me!
You might need to make a Factory for the MyConnectionFactory, but only if you actually need to vary the parameters passed to MyConnectionFactory at runtime. Otherwise, you can get away with making a Provider—which is a Factory after all, I guess—or its slimmer cousin the #Provides Method. (I'm guessing the class in question takes unspecific or primitive arguments, or else a toConstructor binding is yet another possibility.)
The Factory would look like this:
public class MyConnectionFactoryFactory {
#Inject Provider<SomeDependency> someDependencyProvider;
public MyConnectionFactory create(String url) {
return new MyConnectionFactory(someDependencyProvider.get(), url, 10000);
}
}
The Provider would look identical, except it'd implement Provider<MyConnectionFactory> and create would instead be a zero-arg get(). You can bind that through bind(MyConnectionFactory.class).toProvider(MyConnectionFactoryProvider.class).
However, if you know all your constructor parameters at configuration time, you could equally create a #Provides method in your Module, which would look like this:
public class MyModule extends AbstractModule {
#Override public void configure() { /* your configuration here */ }
/* FYI: a #Provides method by any other name would return as sweet */
#Provides MyConnectionFactory getConnectionFactory(SomeDependency dependency) {
return new MyConnectionFactory(dependency, url, 10000);
}
}
...which takes your "wrapper code" boilerplate to three extra non-blank lines. Remember, Guice will automatically bind any combination of X, Provider<X>, or #Provides X to any injection of X or Provider<X> automatically for you, so feel free to bind it however is most convenient.
Maybe someone found a workaround for the following problem:
It seems as if AXIS 1.4 adds an <exceptionName> and a <hostname> element to each custom fault element. In the WSDL the fault is defined to only consist of a custom fault message systemMessage.
This is the answer returned from my service. Never mind about the error, it could be any error that is returned as a fault.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server.generalException</faultcode>
<faultstring/>
<detail>
<ns1:systemMessage xmlns:ns1="http://my.domain/workflow/engine/wsdl/types">
<message>nullcvc-datatype-valid.1.2.1: '2008-12-02T00:00:00' is not a valid value for 'date'.cvc-type.3.1.3</message>
<code>XML string is not valid</code>
<parameter/>
</ns1:systemMessage>
<ns2:exceptionName xmlns:ns2="http://xml.apache.org/axis/">com.domain.commons.ws.schema.SystemMessageType</ns2:exceptionName>
<ns3:hostname xmlns:ns4="http://xml.apache.org/axis/">my.host.com</ns3:hostname>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
It seems as if this is an error in Axis 1.4. Does anyone know a workaround for this behaviour?
There's a workaround for the problem:
In the AXIS generated fault class that extends from org.apache.axis.AxisFault alter the constructors as follows in order to suppress the elements (below is the fault class that is used for the fault returned in the question):
public SystemMessageType() {
// Suppress the two elements
this.removeHostname();
this.removeFaultDetail(org.apache.axis.Constants.QNAME_FAULTDETAIL_EXCEPTIONNAME);
}
public SystemMessageType(
java.lang.String message1,
java.lang.String code,
java.lang.String[] parameter) {
// Call the default constructor
this();
this.message1 = message1;
this.code = code;
this.parameter = parameter;
}
This workaround solves the problem. Nevertheless, whenever you regenerate your code for the SOAP web service you have to adapt the fault class.