I am trying to register different converter instances in the faces-config, using a standard converter class to which different parameters are passed.
The code below registers two DateTimeConverters, the first one for dates including time and the second one for time only. But the pattern property never gets set. Can this be done?
<converter>
<converter-id>dateTimeConverter</converter-id>
<converter-class>javax.faces.convert.DateTimeConverter</converter-class>
<property>
<property-name>pattern</property-name>
<suggested-value>yyyy-MM-dd HH:mm:ss</suggested-value>
</property>
</converter>
<converter>
<converter-id>timeConverter</converter-id>
<converter-class>javax.faces.convert.DateTimeConverter</converter-class>
<property>
<property-name>pattern</property-name>
<suggested-value>HH:mm:ss</suggested-value>
</property>
</converter>
This is unfortunately not possible through faces-config.xml. The <property> declaration which you're trying is not used during runtime.
If all you want is to control the pattern at one place, then best what you can do is to create a custom converter. For this particular purpose it isn't that hard. Just extend DateTimeConverter and set the pattern during construction. Here's a basic example:
public MyDateTimeConverter extends DateTimeConverter() {
public MyDateTimeConverter() {
setPattern("yyyy-MM-dd HH:mm:ss");
}
}
You can of course get the pattern from somewhere else, e.g. a properties file or xml file in classpath.
Register this converter as follows:
<converter>
<converter-for-class>java.util.Date</converter-for-class>
<converter-class>com.example.MyDateTimeConverter</converter-class>
</converter>
That should be it. No need for f:converter or UIOutput#setConverterId().
Related
I'm currently working with citrus-framework to test an application.
One of my interfaces uses Protobuf and I would like to implement a protobuf-to-json-transformer which is compatible with spring-integration to use it similarly like the following but with my transformer instead of the object-to-string-transformer:
<int:channel id="configRawReplies" />
<int:object-to-string-transformer id="configtransformer" input-channel="configRawReplies" output-channel="configResponse" />
<int:channel id="configResponse">
<int:queue />
</int:channel>
for now I have a prototyp exactly like object-to-string-transformer and I'm loading it with:
<bean id="Proto2Json" class="com.nobody.citrus.transformer.ProtoToJSONString">
<property name="input-channel" value="none"/>
<property name="output-channel" value="none"/>
</bean>
but it fails.
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Proto2Json' defined in URL [file:/Users/nobody/DevOops/test/citrus-scala/target/test-classes/citrus-context.xml]:
Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException:
Invalid property 'input-channel' of bean class [com.pme.citrus.transformer.ProtoToJSONString]:
Bean property 'input-channel' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
Does somebody have an idea or an hint where to look on the web?
BR
That's correct. You really need to follow a design in the ObjectToStringTransformer to implement your own AbstractPayloadTransformer. And that one has to be as a plain <bean> definition in your application context.
Only the problem that you don't understand why we really have all those custom tags to utilize input-channel and output-channel attributes as well. The point is that this
<int:object-to-string-transformer>, for example, provides for the application context several beans, including the mentioned ObjectToStringTransformer instance, a MessageTransformingHandler and, finally, ConsumerEndpointFactoryBean to connect a MessageHandler with an inputChannel.
So, what you are missing here is a generic <int:transformer> definition for your custom AbstractPayloadTransformer implementation:
<bean id="Proto2Json" class="com.nobody.citrus.transformer.ProtoToJSONString"/>
<int:tranformer ref="Proto2Json" input-channel="configRawReplies" output-channel="configResponse"/>
Please, read more Reference Manual to avoid similar discussions in the future:
https://docs.spring.io/spring-integration/reference/html/overview.html#programming-tips
https://docs.spring.io/spring-integration/reference/html/messaging-transformation-chapter.html
The following is my configuration xml for a file polling functionality. I have to change the output directory sometimes.
<int-file:inbound-channel-adapter id="filesIn" directory="file:${paths.root}" channel="abc" >
<int:poller id="poller" fixed-delay="5000"/>
</int-file:inbound-channel-adapter>
<int:channel id="abc"/>
<int-file:outbound-channel-adapter channel="abc" id="filesOut"
directory-expression="#aPath.getPath()"
delete-source-files="true"
filename-generator ="filenameGenerator"/>
<bean id="filenameGenerator" class="com.dms.util.FileNameGenerator"/>
In the
#Override
public String generateFileName(Message<?> message)
{
I have tried setting the value of a configured bean property.
This is the additional configuration for that
<bean name="aPath" class="com.dms.util.GetOutPath">
<property name="path" value="${paths.destination}"/>
</bean>
paths.destination is from a property file.
In the generateFileName method I have added the code for changing the property value as follows
#Autowired
private GetOutPath outPathBean;
For the bean:
#Component("outPathBean")
and in my code
outPathBean.setPath(newFolder);
My debugging shows that the value of the property does not change. My question is, How do I modify the directory either in the generateFileName method or by any other way.
Please help!
The general mechanism you are trying to use will work because the file name generator is calle before evaluating the directory expression.
However, you have two instances of you really have the #Component defined (and you are using component scanning, you will have two instances of GetOutPath - aPath and outPathBean.
The expression is using the instance that you are not changing.
You need to inject the same bean instance that you are using in your expression.
I want to create a custom component in JSF and have created it already.Now I want to create attributes for that custom tag that i use in the XHTML file and make them as mandatory.
I have created a component MyJSFComponent extending from UIOutput class. How can i mandate certain attributes?
You don't do that in the UIComponent side, but in the .taglib.xml or TagHandler side.
In the .taglib.xml file you can just add a <required>true</required> entry to the attribute.
<attribute>
<name>foo</name>
<required>true</required>
<type>java.lang.String</type>
</attribute>
You're however dependent on the tooling (the editor) whether this will cause an error or not. JSF/Facelets namely won't check it during runtime. Eclipse for example will automatically inline the attribute when autocompleting the tag in the editor, however it's possible to remove it afterwards and it'll run without errors.
A more solid enforcement is using a ComponentHandler class which offers the getRequiredAttribute() method which would throw TagException when absent. You can then register this handler in .taglib.xml file as follows:
<component>
<component-type>com.example.SomeComponent</component-type>
<handler-class>com.example.SomeComponentHandler</handler-class>
</component>
Whereby the handler class basically look like this:
public class SomeComponentHandler extends ComponentHandler {
public SomeComponentHandler(ComponentConfig config) {
super(config);
getRequiredAttribute("foo");
}
}
This does a real runtime check on the presence of the attribute.
How do you get a reference to the current ActivePivotManger? I've found code that uses it but no way to actually get ahold of it.
If you look at the class SandboxConfig in last v4.4.x you'll see that this class is annotated as following:
#PropertySource(value="classpath:sandbox.properties")
#Configuration
#Import(value={
ActivePivotConfig.class,
ActivePivotServicesConfig.class,
WebServicesConfig.class,
RemotingConfig.class,
SecurityConfig.class
})
public class SandboxConfig {
The ActivePivotConfig.class in the annotation is the one in which we define the activePivotManager which is defined as a member of the SandboxConfig class:
/** ActivePivot Manager, automatically wired */
#Autowired
protected IActivePivotManager activePivotManager;
The #Autowired here is important as it means that this is provided already.
in the previous versions of AP we were defining this as following in our project:
<!-- ActivePivot Manager -->
<bean id="ActivePivotManager" class="com.quartetfs.biz.pivot.impl.ActivePivotManagerFactory">
<property name="resourceName" value="DESC-INF/ActivePivotManager.xml" />
<property name="autoStart" value="false" />
<property name="healthCheckPeriod" value="120"/>
</bean>
If you want to use the ActivePivotManager instance stick then to what is in the SandboxConfig and add your logic there, use the ActivePivotManager instance defined there.
If you're not happy with that move to full XML wiring which is still supported as I can understand that some stuff is hidden and you expect to see the instance of ActivePivotManager instantiated clearly somewhere (which is done actually in ActivePivotConfig.class).
I am trying to set a date/time converter using a theme but I can not get it to work.
I have tried the following and it doesn't work:
<control>
<name>InputField.EditBox</name>
<property mode="override">
<name>converter</name>
<complex type="xp_convertDateTime">
<property>
<name>pattern</name>
<value>DD-MM</value>
</property>
</complex>
</property>
</control>
If at all possible, how do I set a pattern for date/time converters in a theme?
I think the problem is timing. The theme settings are only applied during the render response phase.
The examples that work for complex properties are setting browser-related settings, like dojoAttributes. So the values are applied as the HTML is passed to the browser.
Converters work during the ProcessValidation phase (I've seen that with PhaseListeners). So the converter needs to be there much earlier in the lifecycle.
If I'm right, you won't be able to use a theme to apply a converter. You'd probably need to extend the Edit Box control and create your own component.