ValidateNestedProperties field sorting - java

Good day,
I have some mandatory field need to validate when running update() method. The validation is working fine. But I fail to sort the sequence.
My code is as follow:
#ValidateNestedProperties({
#Validate(field = "currentPassword", on = { "update" }, required = true, mask = "^([^\\s]+)$"),
#Validate(field = "newPassword", on = { "update" }, required = true, mask = "^([^\\s]+)$"),
#Validate(field = "confirmPassword", on = { "update" }, required = true, mask = "^([^\\s]+)$") })
And the screen in browser will show as follow:
- Confirm Password is a mandatory field
- Current Password is a mandatory field
- New Password is a mandatory field
I guess it display sort by ascending order, but actually I wish to display at my own ways, which is currentPassword, then newPassword, and then confirmPassword.
I tried google on this but I think my question is wrong thus I cant get the correct response.
Kindly advise.

The easiest way to achieve that is to specify the error messages in the desired order in the output:
<stripes:errors field="currentPassword"/>
<stripes:errors field="newPassword"/>
<stripes:errors field="confirmPassword"/>
If there may be additional errors not bound to a field show them like so:
<stripes:errors globalErrorsOnly="true"/>
Sorting is tricky since error messages are kept in a HashMap. I suppose you would have to write your own implementation.
See this great article on the Stripes site: https://stripesframework.atlassian.net/wiki/display/STRIPES/Display+Errors
And the docs: http://stripes.sourceforge.net/docs/current/taglib/index.html

Related

How to get all videos from my own YouTube channel via YouTube Data API v3

I need to get the ID and title for all videos from my own YouTube channel. Some of videos are unlisted, but I want to get them too. I use this version of the client library:
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-youtube</artifactId>
<version>v3-rev222-1.25.0</version>
</dependency>
According to the documentation I use this Java code:
YouTube.Search.List request = youtubeService.search()
.list("id,snippet");
SearchListResponse response = request.setChannelId(channelId)
.setForMine(true)
.setMaxResults(50L)
.setType("video")
.execute();
But got this exception:
400 Bad Request
GET https://www.googleapis.com/youtube/v3/search?channelId=channelId&forMine=true&maxResults=50&part=id,snippet&type=video
{
"code" : 400,
"errors" : [ {
"domain" : "youtube.search",
"location" : "parameters.",
"locationType" : "other",
"message" : "The request contains an invalid combination of search filters and/or restrictions. Note that you must set the <code>type</code> parameter to <code>video</code> if you set either the <code>forContentOwner</code> or <code>forMine</code> parameters to <code>true</code>. You must also set the <code>type</code> parameter to <code>video</code> if you set a value for the <code>eventType</code>, <code>videoCaption</code>, <code>videoCategoryId</code>, <code>videoDefinition</code>, <code>videoDimension</code>, <code>videoDuration</code>, <code>videoEmbeddable</code>, <code>videoLicense</code>, <code>videoSyndicated</code>, or <code>videoType</code> parameters.",
"reason" : "invalidSearchFilter"
} ],
"message" : "The request contains an invalid combination of search filters and/or restrictions. Note that you must set the <code>type</code> parameter to <code>video</code> if you set either the <code>forContentOwner</code> or <code>forMine</code> parameters to <code>true</code>. You must also set the <code>type</code> parameter to <code>video</code> if you set a value for the <code>eventType</code>, <code>videoCaption</code>, <code>videoCategoryId</code>, <code>videoDefinition</code>, <code>videoDimension</code>, <code>videoDuration</code>, <code>videoEmbeddable</code>, <code>videoLicense</code>, <code>videoSyndicated</code>, or <code>videoType</code> parameters."
}
Moreover I got the same error using interactive tool on this page:
https://developers.google.com/youtube/v3/docs/search/list?apix=true.
If I remove .setForMine(true) it works fine, but doesn't give me unlisted videos (gives me only public videos).
Are there any possibilities to get the ID and title of all videos (unlisted included) from my own channel via the API?
The short answer to your question is: indeed, there is an API that will provide all video metadata of your channel, including the metadata of unlisted videos.
For the longer answer, just bear with me for a while:
First thing, do note that a given video has a privacy status of the following kinds:
status.privacyStatus (string)
The video's privacy status.
Valid values for this property are:
private
public
unlisted
For to obtain the IDs of all videos uploaded by your channel, irrespective of their privacy status, you'll have to invoke the PlaylistItems.list API endpoint queried with the parameter playlistId set to the ID of your channel's uploads playlist, while issuing an OAuth authorized request (that is: passing to the API a valid access token; using only an API key will make the endpoint return only public videos):
List<String> scopes = Lists.newArrayList(
"https://www.googleapis.com/auth/youtube.readonly"); // or ".../auth/youtube"
Credential credential = Auth.authorize(scopes, "myuploads");
youtube = new YouTube.Builder(
Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential)
.setApplicationName("myuploads")
.build();
List<String> videoIdList = new ArrayList<String>();
YouTube.PlaylistItems.List playlistItemRequest =
youtube.playlistItems().list("contentDetails");
playlistItemRequest.setFields("nextPageToken,items/contentDetails/videoId");
playlistItemRequest.setMaxResults(50);
playlistItemRequest.setPlaylistId(uploadsPlaylistId);
String nextToken = "";
do {
playlistItemRequest.setPageToken(nextToken);
PlaylistItemListResponse playlistItemResult = playlistItemRequest.execute();
for (PlaylistItem playlistItem: playlistItemResult.getItems())
videoIdList.add(playlistItem.getContentDetails().getVideoId());
nextToken = playlistItemResult.getNextPageToken();
} while (nextToken != null);
Now, the Videos.list API endpoint will provide you all the metadata of the videos of which IDs are collected by videoIdList.
List<Video> videoList = new ArrayList<Video>();
while (videoIdList.size() > 0) {
int endIndex = videoIdList.size() < 50 ? videoIdList.size() : 50;
List<String> subList = videoIdList.subList(0, endIndex);
YouTube.Videos.List videosRequest =
youtube.videos().list("id,contentDetails,status,snippet, statistics");
videosRequest.setId(String.join(",", subList));
VideoListResponse videosResponse = videoRequest.execute();
videoList.AddAll(videosResponse.getItems());
subList.clear();
}
Note that, if videoIdList is of size N at the beginning of the loop above -- since the parameter id of Videos.list endpoint can be specified as a comma-separated list of video IDs --, the loop code reduces the number of calls to Videos.list endpoint from N to Math.floor(N / 50) + (N % 50 ? 1 : 0) by appropriately using the feature of id just mentioned.
The uploads playlist ID -- uploadsPlaylistId -- may very easily be obtained by invoking the Channels.list endpoint queried with the parameter id set to your channel's ID, or, otherwise, queried with the parameter mine set to true:
YouTube.Channels.List channelRequest =
youtube.channels().list("contentDetails");
channelRequest.setMine(true);
channelRequest.setFields("items/contentDetails/relatedPlaylists/uploads");
ChannelListResponse channelResult = channelRequest.execute();
Note that above I used the fields parameter for to get from the API only the info that's needed.
The uploads playlist ID is then to be found within the endpoint's JSON response as value of the property:
items[0].contentDetails.relatedPlaylists.uploads.
Translated to Java, this property path would become the following chain of getters, ending with getUploads:
channelResult.getItems().get(0).getContentDetails().getRelatedPlaylists().getUploads().
Note that for a given channel, you need to obtain the uploads playlist ID only once, then use it as many times as you wish. Usually, a channel ID and its corresponding uploads playlist ID are related by s/^UC([0-9a-zA-Z_-]{22})$/UU\1/.
For an almost complete implementation of the API calls I described above (excluding the loop that fills up the list videoList), I'll recommend to make use of the following sample program from Google: MyUploads.java. The loop that constructs the list videoList is similar to the one found in GeolocationSearch.java. The implementation of method Auth.authorize is to be found in Auth.java.

Java Selenium - Find string text from multiple divs with same class name using xpath

i'm hoping you can help me.
I've been going through all sorts of forums and questions on here on how to cycle through multiple divs with the same class name using xpath queries. I'm fairly new to WebDriver and Java so I'm probably not asking the question properly.
I have a table where i'm trying to identify the values within and ensure they're correct. each field has the same class identifier, and i'm able to successfully pull back the first result and confirm via report logging using the following
String className1 = driver.findElement(By.xpath("(//div[#class='table_class'])")).getText();
Reporter.log("=====Class Identified as "+className1+"=====", true);
However, when i then try and cycle through (I've seen multiple answers saying to add a [2] suffix to the xpath query) i'm getting a compile error:
String className2 = driver.findElement(By.xpath("(//div[#class='table_class'])")[2]).getText();
Reporter.log("=====Class Identified as "+className2+"=====", true);
The above gives an error saying "The type of the expression must be an array type but it resolved to By"
I'm not 100% sure how to structure this in order to set up an array and then cycle through.
Whilst this is just verifying field labels for now, ultimately i need to use this approach to verify the subsequent data that is pulled through, and i'll have the same problem then
You are getting the error for -
String className2 = driver.findElement(By.xpath("(//div[#class='table_class'])")[2]).getText();
because you are using index in wrong way modify it to -
String className2 = driver.findElement(By.xpath("(//div[#class='table_class'])[2]")).getText();
or
String className2 = driver.findElement(By.xpath("(//div[#class='table_class'][2])")).getText();
And the better way to do this is -
int index=1;
List <WebElement> allElement = driver.findElements(By.xpath("(//div[#class='table_class'])"));
for(WebElement element: allElement)
{
String className = element.getText();
Reporter.log("=====Class Identified as "+className+""+index+""+"=====", true);
index++
}

Get path variable out of HttpMessageNotReadable exception

We have some web services which are being consumed by mobile clients , in which the mobile clients make some request's and we return response to them. Somehow if the client make any invalid request we throw Custom Exceptions .But recently the mobile client has made some request which was out of range for Long variable. The client has different variables for ex ::
{
"accountId":"343"
"Amount":"90909090909090909090"
}
In case of the value for accountId or Amount are made more than 19 digits we get HttpMessageNotReadable exception as the range is out of long value. But from exception i am not able to fetch for which variable the exception has been raised whether for accountId or Amount. From the exception i am getting this information in _path variable but i am not able to fetch it.
And in the path variable i get something like::
[com.Upload["AccountInfo"], com.Info["Account"]]
Does somebody know how to fetch this information.
The following code prints out the field which causes the exception.
InvalidFormatException invalidFormatException = (InvalidFormatException) exception
.getCause();
System.out.println(invalidFormatException.getPath().get(0)
.getFieldName());
#ArunM's answer works as long as the field is in 1st level viz the example given by OP.
But what happens when the field is in nested json? say paymentType has wrong value in the following example?
{
"userType": "CUSTOMER",
"payment": {
"amount": 123456,
"paymentType": "INTERNET_BANKING"
}
}
In the above example, if there's anything wrong with the value of userType, there will be just one element in _path.
But if any value inside the payment is wrong, say for example paymentType, there will be multiple elements in the _path variable. Each element representing the hierarchical attribute.
So for paymentType, _path will have 2 elements as illustrated below:
_path[0].fieldName = "payment"
_path[1].fieldName = "paymentType"
Hence the correct approach is to get the last element in _path as shown below. If needed, we can build the complete path by using all the elements.
InvalidFormatException ifx = (InvalidFormatException) exception.getCause();
System.out.println(ifx.getPath().get(ifx.size() - 1).getFieldName());
This I believe is the right approach to get the invalid attribute name.

PF datatable value and filteredValue - best practise

I should have asked this question way earlier but now I am really tired of dodging around this problem:
I have a normal datatable like
<p:dataTable id="dt1" var="tVar" value="#{mrBean.queriedElements}" filteredValue="#{mrBean.filteredElements}" ...
Now in addition to the primefaces filters, I made my own panelGrid in which you can apply filters to the data base which work before any PF action.
The following lists exist: queriedElements which holds all the data that is returned after my personal filter applied and filteredElements which is needed for primefaces datatable filtering. In addition, I am not exactly sure whether I need an element list that represents all the data from the database. If no personal filter is applied, queriedElements = allElements.
The datatable displays a lot of information on the objects contained and you can change these objects via a dialog. I want the following:
When saved, update all changes made to the selectedElement
When cancelled, revert all changes in the datatable (I dont use a temporary object that is edited but the very object from the list)
When closing the dialog, remember all filters and paginator position
What is the best practise to do so and how can I avoid redundant code for queriedElements and filteredElements (in case I must iterate through it to change it explicitly in addition to database merges)? I found the first attribute for pagination, but I'm not really sure how to use it properly combined with my other requirements. My main problem is that the datatable almost never displays the right values if I don't refetch from database.
PF 4.0
I don't know why PF 4.0 doesn't do this by itself, but something that worked for me can be found at http://www.brainhemorage.com/?p=258
Although I had to replaced the lines
ValueExpression filterBy = column.getValueExpression("filterBy");
String filterField = null;
if (filterBy != null)
filterField = table.resolveStaticField(filterBy);
String filterId = column.getContainerClientId(context) + separator + "filter";
String filterValue = params.containsKey(filterId) && !table.isReset() ? params.get(filterId) :
table.getFilters().get(filterField); // <-- and here, was ""
String filterStyleClass = column.getFilterStyleClass();
by
String filterId = column.getContainerClientId(context) + separator + "filter";
String filterValue = params.containsKey(filterId) && !table.isReset() ? params.get(filterId) :
table.getFilters().get(column.getFilterBy());
because getValueExpression always returned null.
Although this doesn't answer my question about the BP, this will surely help others with the filteredValue problem.

Read Facebook Post-related Object with Spring Social

I read all my likes using FQL with Spring Social Facebook
here is the method:
public List<LikeObject> startF(String token){
Facebook facebook = new FacebookTemplate(token);
FacebookProfile profile = facebook.userOperations().getUserProfile();
//System.out.println(facebook.isAuthorized());
System.out.println("Authenticcated user: "+profile.getFirstName()+" "+profile.getLastName());
PagedList<String> friendListIds = facebook.friendOperations().getFriendIds();
List<LikeObject> resultsLikes = facebook.fqlOperations().query("SELECT object_id, object_id_cursor,object_type, post_id, post_id_cursor, user_id "+
"FROM like "+
"WHERE user_id =me() ", new FqlResultMapper<LikeObject>(){
public LikeObject mapObject(FqlResult result) {
LikeObject like = new LikeObject();
like.object_id = result.getString("object_id");
like.object_id_cursor = result.getString("object_id_cursor");
like.object_type = result.getString("object_type");
like.post_id = result.getString("post_id");
like.post_id_cursor = result.getString("post_id_cursor");
like.user_id = result.getString("user_id");
return like;
}
});
return resultsLikes;
}
Here results:
LikeObject [object_id=578416.., object_id_cursor=null,
object_type=status, post_id=, post_id_cursor=null, user_id=10217..]
Then I would like to parse like.object_id and convert it to java object. But I've no idea how to do it using spring social facebook.
I've tried facebook.fetchObject(like.object_id, PostType.STATUS) . But it seems to be a wrong way.
Is there any possible way to parse an "object_id" in spring social without parsing raw JSON response from GET query?
I've tried this:
LinkPost post = facebook.fetchObject(obj_id, LinkPost.class);
I believe that obj_id has type link, I've checked it
and it cause following exception:
Exception in thread "main" org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'postType' that is to contain type id (for class org.springframework.social.facebook.api.LinkPost)
at [Source: java.io.ByteArrayInputStream#6ca79a6a; line: 1, column: 11114]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'postType' that is to contain type id (for class org.springframework.social.facebook.api.LinkPost)
at [Source: java.io.ByteArrayInputStream#6ca79a6a; line: 1, column: 11114]
at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType(MappingJackson2HttpMessageConverter.java:171)
at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.read(MappingJackson2HttpMessageConverter.java:163)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:94)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:491)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:460)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:228)
at org.springframework.social.facebook.api.impl.FacebookTemplate.fetchObject(FacebookTemplate.java:202)
at com.repost.facebook.FbConnection.getLikedPosts(FbConnection.java:58)
at com.repost.facebook.MainClass.main(MainClass.java:15)
I'm still unclear what you mean by "parse". But let me attempt to answer this anyway...
I think you simply want to be able to fetch the object as a Post (or LinkPost) object...is that right? If so, then there's some special magic that I unfortunately had to bake into the API to be able to both grab the post type and do polymorphic deserialization into a specific type of Post (e.g., LinkPost, StatusPost, etc).
You can see the setup taking place in https://github.com/SpringSource/spring-social-facebook/blob/master/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/FeedTemplate.java. In the deserializePost() method, you see that I read the "type" property and copy it into a new "postType" field. One of those fields is used to populate the Post's type property and the other is used to determine which specific subclass of Post should be created. It's a hack to work around a problem I had with Jackson 1.9.x...I think that Jackson 2 will make that hack unnecessary, but I've not tried it yet.
Therefore, I see only one practical way of doing this: Don't do all the work yourself. Instead use facebook.feedOperations().getPost(objectId). It knows how to do the magic under the covers to give you a Post object. From there, if you know the specific kind of Post, you can cast it as (and if) needed to LinkPost, StatusPost, etc.
The only other option I see is to go even lower level and make the request through facebook.restOperations() and to handle the binding for yourself. That's obviously a lot more work on your part.

Categories

Resources