ADF problems with af:validateRegExp (binding Long field) - oracle-adf

I have a portlet application in a WebCenter env. This application is made using JSF (with the ADF implementation), so I have a field like that:
<af:inputText visible="#{CadastrarFormularioContato.showCodigoEc}"
label="#{msg.CODIGODOEC}" id="it2" required="true"
requiredMessageDetail="#{msg.INFORMECODIGOEC}"
showRequired="true"
value="#{CadastrarFormularioContato.item.cdEstabelecimento}">
<af:validateRegExp messageDetailNoMatch="#{msg.CODIGOECSOMENTENUMEROS}" pattern="^[0-9]{1,}$"/>
<af:convertNumber type="number"/>
</af:inputText>
But, when I invoke the form submit i receive the follow error:
javax.portlet.faces.BridgeException: java.lang.IllegalArgumentException: 'value' is not of type java.lang.String.
My Object.longField is:
private Long longField
(with its getters/setters)
I try to use convert, convertNumber etc but with no sucess.
The problem is about the "validateRegExp" tag (if i remove it, works) So, why?
Any suggestion?

The validateRegExp only accepts Strings. If you can change the java class, then adding a String field to shadow the Long is an easy fix. If not, you can write your own regex validator.

Related

af:inputFile is not calling valueChangeListener method

Summarize the problem
I'm trying to upload an image to a blob in the database and have been following various blogs online to do so.
Provide background including what you've already tried
I've tried enclosing the input file on a form but I get the warning:-
"Only one af:form is supported per page. This warning later escalates to a server exception error and I can't enter said page.
Show some code
<af:panelFormLayout id="pfl1">
<f:facet name="footer"/>
<af:form id="f1" usesUpload="true">
<af:inputFile label="Label 1" id="if1" value="#NewUploadImageBean.file}"
valueChangeListener="#{NewUploadImageBean.upLoadValueChangeListener}"/>
</af:form>
</af:panelFormLayout>
I only have this one form in the entire page.
Describe expected and actual results including any error messages
Would like to the valueChangeListner to call my method. Currently I get the
ADF_FACES-60097 error which then translates to : java.lang.IllegalStateException: ADF_FACES-30124:Multiple forms detected on viewId: /test_pages/employement.jsf. Rich client currently has some limitations in dealing with multiple forms.
How to fix ADF_FACES-30124:Multiple forms detected on viewId ?
To do so remove all the af:forms inside your jsf view expecially the one containing your inputFile and add only one af:form useupload="true" at the highest view tag level :
<af:document >
<af:form usesUpload="true" id="f1">
... ALL YOUR VIEW TAGS ...
</af:form>
</af:document>

camel - spring:bean syntax with dynamic class casting

I'm attempting to convert the following Java object initalization with dynamic class casting to camel spring bean syntax. I'm adding my broken spring bean sample as well. I dont have much familiarity with spring beans, so would very much appreciate some input. The Java syntax is:
import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider;
STSAssumeRoleSessionCredentialsProvider credentials = new STSAssumeRoleSessionCredentialsProvider.Builder(
"arn:aws:iam::***:role/myRole-QA", "sessionName").build();
and broken spring bean:
<spring:bean id="sqsCredentials" class="com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider.Builder" >
<spring:constructor-arg index="0" value="arn:aws:iam:***:role/myRole-QA" />
<spring:constructor-arg index="1" value="sessionName" />
<spring:property name="targetMethod">
<spring:value>build</spring:value>
</spring:property>
</spring:bean>
I'm not sure if what I have for method build is correct, but there are two classes at play: .Builder and just STSAssumeRoleSessionCredentialsProvider. So Builder class returns STSAssumeRoleSessionCredentialsProvider. Most likely i have more then one issue to solve here, but the error I think is related to class mismatch ... much appreciate your time:
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'targetMethod' of bean class
[com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider$Builder]: Bean property 'targetMethod' is not writable
or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

Using d-bus to change volume with bluez 5.43 on C.H.I.P

I'm new to d-bus and bluez. I have a CHIP module, running as a BT speaker. I followed this:
https://github.com/hadess/CHIP-bluetooth-speaker
and also the instructions in the following link to get iPhone volume working:
https://github.com/hadess/CHIP-bluetooth-speaker/issues/8
I'd like to be able to change the volume of the speaker both from my iphone and from the module - so I'm guessing dbus commands is the way to go.
I've successfully connected and disconnected from my iPhone using:
dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_A0_D7_95_A9_88_91 org.bluez.Device1.Disconnect
and d-feet was useful to show me how to do it. However, I'm not clear on how I can do play/pause/volumeUp/volumeDown. The documentation here:
https://kernel.googlesource.com/pub/scm/bluetooth/bluez/+/5.43/doc/media-api.txt
explains how to do play/pause but I can't get it to work. I've tried:
dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_A0_D7_95_A9_88_91 org.bluez.MediaPlayer1.Pause
and:
dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_A0_D7_95_A9_88_91/Player1 org.bluez.MediaPlayer1.Pause
with the same error:
Error org.freedesktop.DBus.Error.UnknownMethod: Method "Pause" with signature "" on interface "org.bluez.MediaPlayer1" doesn't exist
and I'm not at all clear how to change volume (the VolumeUp and VolumeDown commands in mediacontrol1 as shown as deprecated).
Can anyone help?
Update
After great comments from Constantin below (thanks), I'd like some more clarification.
Using d-feet, I get the following information for my device:
should I be able to see a "MediaTransport1" and/or "MediaControl1" interface entry in the listing?
When I call the introspective for device1, I get:
'<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"\n"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">\n<node><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg name="xml" type="s" direction="out"/>\n</method></interface><interface name="org.bluez.Device1"><method name="Disconnect"></method><method name="Connect"></method><method name="ConnectProfile"><arg name="UUID" type="s" direction="in"/>\n</method><method name="DisconnectProfile"><arg name="UUID" type="s" direction="in"/>\n</method><method name="Pair"></method><method name="CancelPairing"></method><property name="Address" type="s" access="read"></property><property name="Name" type="s" access="read"></property><property name="Alias" type="s" access="readwrite"></property><property name="Class" type="u" access="read"></property><property name="Appearance" type="q" access="read"></property><property name="Icon" type="s" access="read"></property><property name="Paired" type="b" access="read"></property><property name="Trusted" type="b" access="readwrite"></property><property name="Blocked" type="b" access="readwrite"></property><property name="LegacyPairing" type="b" access="read"></property><property name="RSSI" type="n" access="read"></property><property name="Connected" type="b" access="read"></property><property name="UUIDs" type="as" access="read"></property><property name="Modalias" type="s" access="read"></property><property name="Adapter" type="o" access="read"></property></interface><interface name="org.freedesktop.DBus.Properties"><method name="Get"><arg name="interface" type="s" direction="in"/>\n<arg name="name" type="s" direction="in"/>\n<arg name="value" type="v" direction="out"/>\n</method><method name="Set"><arg name="interface" type="s" direction="in"/>\n<arg name="name" type="s" direction="in"/>\n<arg name="value" type="v" direction="in"/>\n</method><method name="GetAll"><arg name="interface" type="s" direction="in"/>\n<arg name="properties" type="a{sv}" direction="out"/>\n</method><signal name="PropertiesChanged"><arg name="interface" type="s"/>\n<arg name="changed_properties" type="a{sv}"/>\n<arg name="invalidated_properties" type="as"/>\n</signal>\n</interface></node>'
Which doesn't have any details in for volume, transport control etc. Does that mean my bluez setup isn't permitting it?
Ultimately, I'd like to get this all working within Python so, Constantin, if you can continue your great support, some examples of python code would also be great.
Update 2
Ok, so trying this on a Rpi V3 with Bluez v5.23 and I get:
pi#raspberrypi:~ $ qdbus --system org.bluez /org/bluez/hci0/dev_A0_D7_95_A9_88_91
method QString org.freedesktop.DBus.Introspectable.Introspect()
property read QDBusObjectPath org.bluez.Device1.Adapter
property read QString org.bluez.Device1.Address
property readwrite QString org.bluez.Device1.Alias
property read ushort org.bluez.Device1.Appearance
property readwrite bool org.bluez.Device1.Blocked
property read uint org.bluez.Device1.Class
property read bool org.bluez.Device1.Connected
property read QString org.bluez.Device1.Icon
property read bool org.bluez.Device1.LegacyPairing
property read QString org.bluez.Device1.Modalias
property read QString org.bluez.Device1.Name
property read bool org.bluez.Device1.Paired
property read short org.bluez.Device1.RSSI
property readwrite bool org.bluez.Device1.Trusted
property read QStringList org.bluez.Device1.UUIDs
method void org.bluez.Device1.CancelPairing()
method void org.bluez.Device1.Connect()
method void org.bluez.Device1.ConnectProfile(QString UUID)
method void org.bluez.Device1.Disconnect()
method void org.bluez.Device1.DisconnectProfile(QString UUID)
method void org.bluez.Device1.Pair()
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface, QString name)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface)
signal void org.freedesktop.DBus.Properties.PropertiesChanged(QString interface, QVariantMap changed_properties
method void org.freedesktop.DBus.Properties.Set(QString interface, QString name, QDBusVariant value)
property read bool org.bluez.MediaControl1.Connected
method void org.bluez.MediaControl1.FastForward()
method void org.bluez.MediaControl1.Next()
method void org.bluez.MediaControl1.Pause()
method void org.bluez.MediaControl1.Play()
method void org.bluez.MediaControl1.Previous()
method void org.bluez.MediaControl1.Rewind()
method void org.bluez.MediaControl1.Stop()
method void org.bluez.MediaControl1.VolumeDown()
method void org.bluez.MediaControl1.VolumeUp()
... so MediaControl1 is shown.
Question is, is it due to the different version of Bluez or the different platform? It's also a bit slow to respond to the dbus commands (which I wasn't expecting). Sometimes it's almost immediate, other times is could take 1-2 seconds. Is that expected?
First of all, you were in the right way when adding "Player1" to your object path, the documentation clearly states :
Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX
However, how did you find that "Player1" ? This must not be a random number, you will find the exact string you have to append to the mac address by Introspecting your device (object path with dev_XX_XX...), usually in an xml tag ''
Now about your error, I know the documentation states that the Pause method does not take arguments, though maybe the documentation is not up-to-date ?
One easy way to know a bit more about methods from the dbus is to analyze introspection :
You can use the following command to retrieve the introspection (you should update the path after hci0 to match your object path) :
dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0 org.freedesktop.DBus.Introspectable.Introspect
To give you an example, the following is extracted from an introspection :
<method name="GetAll"><arg name="interface" type="s" direction="in"/><arg name="properties" type="a{sv}" direction="out"/>
From this I learn that the GetAll method takes as argument (direction in, type s) the interface name as a string, and returns a dictionary where strings(keys) are mapped to variants(values) (direction out, type a{sv})
Could you introspect your device and make sure you find that "Player1" node tag ? Then introspect that Player1 and make sure the Pause method does not take any argument.
To change the volume, I guess you're supposed to the use "Volume" property from the Interface org.bluez.MediaTransport1 (look at the end of the media-api.txt file).
Finally, do you plan to include these manipulations in a program ? If yes, I suggest using dbus bindings in the appropriate language (C, Glib, Python, C#...). I can give you more documentation on how to interact with bluez in a program.
UPDATE
The version on your rpi (5.23) is old and uses an API which is now deprecated (see for yourself the org.bluez.MediaControl1 interface has [Deprecated] everywhere here https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/media-api.txt)
By looking at the doc, theres no interfaces you should be able to see when introspecting the device. org.bluez.Media1 should appear if you introspect /org/bluez/hci0 (refering to the specified Object path).
Service org.bluez
Interface org.bluez.Media1
Object path [variable prefix]/{hci0,hci1,...}
And org.bluez.MediaPlayer1 should appear when introspecting the player :
Service org.bluez (Controller role)
Interface org.bluez.MediaPlayer1
Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/playerX
Though in your case, I see nothing related to that "playerX" in your introspection and that's the issue that need to be fixed first.
To stream sound over Bluetooth, you want to use the A2DP Protocol with your linux as "source" and your speaker as "sink". This functionality (audio streaming) might require PulseAudio. Try to add the latest version of pulseaudio to your system (you might want to compile from sources). See here for the details : https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Bluetooth/
Maybe your rpi uses bluez4 and pulseaudio configured to connect automatically. This would explain why you can see the interfaces on the rpi.
There is also the Arch Wiki that can help for troubleshooting: https://wiki.archlinux.org/index.php/Bluetooth_headset#Headset_via_Bluez5.2FPulseAudio
While I was looking for information I found this website : http://www.lightofdawn.org/wiki/wiki.cgi/BluezA2DP
It describes how to use the bluez api to make it work for A2DP. The tutorial was written for bluez4 and the author talks about bluez5 compatibility at the end.
I can't tell exactly what actions and in what order you'll need to do, although you will find plenty of documentation and tutorials when googling "bluez a2dp python" (like this one on reddit, read carefully his comments at the top of his code file) : https://www.reddit.com/r/Python/comments/1f1xkt/use_python_to_turn_your_bluetooth_laptop_into_a/)
My guess is that you'll need to scan (org.bluez.Adapter1) ,register endpoint (org.bluez.Media1), pair (and maybe connect ? using org.bluez.Device1)and acquire a file descriptor for writing (org.bluez.MediaTransport1)
Before doing anything else, you'll need to see thoses interfaces using d-feet ! Once you have it working with d-feet, you can refer to this gist for a simple python example that will perform a scan : https://gist.github.com/CynaCons/8eb02540f87af5594fac489a9dca32c1
I've also uploaded an advanced version on github gist.

ADF remove required asterisk

I have a panelLabelAndMessage containing inputComboboxListOfValues and outputText. The LOV is a mandatory field and hence it has the asterisk beside it. But I have changed simple property to true as I did not want to show label of LOV ans assigned the same label to panelLabelAndMessage. Also changed showrequired property to true for the asterisk. But now the LOV field is also showing asterisk which is undesirable. Any way to remove the star mark but still have the model level validation in place.
I do not want to use required property of LOV.
The code for my label and fields is as below.
<af:panelLabelAndMessage label="#{bindings.Department.label}"
id="plam1"
showRequired="#{bindings.Department.hints.mandatory}">
<af:panelGroupLayout id="pgl1" layout="horizontal">
<af:inputComboboxListOfValues id="DepartmentId"
popupTitle="Search and Select: #{bindings.DepartmentId.hints.label}"
value="#{bindings.DepartmentId.inputValue}"
model="#{bindings.DepartmentId.listOfValuesModel}"
columns="#{bindings.DepartmentId.hints.displayWidth}"
shortDesc="#{bindings.DepartmentId.hints.tooltip}"
required="#{bindings.DepartmentId.hints.mandatory}"
autoSubmit="true"
binding="#{backingBeanScope.BackingBean.departmentLov}"
valueChangeListener="#{backingBeanScope.BackingBean.onSelectDepartment}">
<f:validator binding="#{bindings.DepartmentId.validator}"/>
<af:convertNumber groupingUsed="false"
pattern="#{bindings.DepartmentId.format}"/>
</af:inputComboboxListOfValues>
<af:spacer width="10" height="10" id="s1"/>
<af:outputText value="#{bindings.DepartmentName.inputValue}" id="ot1"
partialTriggers="DepartmentId"
binding="#{backingBeanScope.BackingBean.DepartmentName}"/>
</af:panelGroupLayout>
</af:panelLabelAndMessage>
To answer to core question (can you remove the asterisk ): Yes, by using ADF Skinning.
Some examples:
.hideRequired af|selectOneChoice::label af|panelFormLayout::label-cell .AFRequiredIconStyle,
.hideRequired af|panelFormLayout::label-cell .AFRequiredIconStyle,
.hideRequired af|selectOneChoice::label .AFRequiredIconStyle
{
display:none ;
}
Note that we add hideRequired as a styleClass to the component (you can give it an other name).
The one you will probably need to use is:
.hideRequired af|inputComboboxListOfValues::label .AFRequiredIconStyle
{
display:none;
}
Remove required property, the validation will still fire for LOV.
But since you have skipValidtion set to true therefore the model level validation will also not fire.
Here is how you implement required field validation without using required="true" or model level validation in Jdeveloper 11.1.2.* or higher, as this solution does not works for versions older than JSF2.0
Create a validator method in your managed bean, or if you want to reuse the validator then create a custom validator for your application.
public void requiredFieldValidator(FacesContext facesContext, UIComponent uIComponent, Object object) {
if (null == object) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "This field can not be empty",
null));
}
else{
if(object.toString().trim().equals("")){
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "This field can not be empty",
null));
}
}
}
Use this method as your lov validator
<af:inputListOfValues label="Lov1" popupTitle="Search and Result Dialog" id="ilov1"
validator="#{pageFlowScope.mBean.emailValidator}"/>
More importantly, to make validator works on empty fields, set javax.faces.VALIDATE_EMPTY_FIELDS to true in your web.xml
<context-param>
<param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
<param-value>true</param-value>
</context-param>

Generate and download file with jboss seam

I need to add an 'export' function to an existing web app using seam. The purpose is to export search results to a csv file. I have no problem generating a csv, but I do not know how the send the csv back to the user.
I do not want to store the csv on the server because that would be waisted storage space. How could I achieve this in jboss seam?
Use the Document Store Servlet provided by Seam.
Almost copying and pasting from the reference doc, declare the servlet in web.xml like this:
<servlet>
<servlet-name>Document Store Servlet</servlet-name>
<servlet-class>org.jboss.seam.document.DocumentStoreServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Document Store Servlet</servlet-name>
<url-pattern>/seam/docstore/*</url-pattern>
</servlet-mapping>
Then create a export.xhtml file with only <s:resource> tag:
<s:resource xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
data="#{myComponent.csvData}"
contentType="application/vnd.ms-excel"
fileName="#{myComponent.csvFileName}"/>
Generate link for downloading the file in your page with <s:download>:
<s:download src="/csv/export.xhtml">
<h:outputText value="Download CSV"/>
<f:param name="param1" value="somevalue"/>
<f:param name="param2" value="someOtherValue"/>
</s:download>
Finally, implement getCsvData() and getCsvFileName() methods in your component:
// could be byte[], File or InputStream
public InputStream getCsvData() {
// generate data to be downloaded
}
public String getCsvFileName() {
return "myfile.csv";
}
Note that <s:download> propagates conversation (unless you set propagation=none). If you propagate the conversation context probably you won't need to pass any parameter. For large data set it may be preferable to not propagate the conversation and pass parameter to select the data in a request scoped component.
There's a couple of ways:
1) Check the Seam docs for info on using Seam-Excel to programmatically generate your file and then write it out using a mime-type set for CSV - this is all detailed in the docs.
However, I could not get this to work in the latest version of Seam, as it requires a response object, which used to be available from the Seam context but now only returns null.
2) Code the CSV file you want as an Excel xhtml template (see the Seam docs and example projects) and simply render this as normal using an tag.
I do this regularly and it works well, bar the restriction that you cannot supply a filename.
HTH.

Resources