I'm trying to do this:
NewRoomate(int studentID, List<Integer> rankedQuestions, boolean...trueFalseQuestions){
this.studentID = studentID;
this.rankedQuestions = rankedQuestions;
List<Boolean> wef = Arrays.asList(trueFalseQuestions);
}
But the compiler doesn't like it.
Problems:
How can I convert all of the booleans in the trueFalseQuestions array to a List?
Change boolean...trueFalseQuestions to Boolean...trueFalseQuestions
Result will be:
NewRoomate(int studentID, List<Integer> rankedQuestions, Boolean...trueFalseQuestions){
this.studentID = studentID;
this.rankedQuestions = rankedQuestions;
List<Boolean> wef = Arrays.asList(trueFalseQuestions);
}
NewRoomate(int studentID, List<Integer> rankedQuestions, Boolean...trueFalseQuestions){
this.studentID = studentID;
this.rankedQuestions = rankedQuestions;
List<Boolean> wef = Arrays.asList(trueFalseQuestions);
}
Just make it to Boolean from boolean.
NewRoomate(int studentID, List<Integer> rankedQuestions, boolean...trueFalseQuestions){
this.studentID = studentID;
this.rankedQuestions = rankedQuestions;
List<Boolean> wef = new ArrayList<Boolean>(); //initiate your list
for(boolean question : trueFalseQuestions){ //fill your list with questions
wef.add(question);
}
}
Related
I'm upgrading some legacy to target Android Q, and of course this code stop working:
String[] PROJECTION_BUCKET = {MediaStore.Images.ImageColumns.BUCKET_ID,
MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.DATA,
"COUNT(" + MediaStore.Images.ImageColumns._ID + ") AS COUNT",
MediaStore.Files.FileColumns.MEDIA_TYPE,
MediaStore.MediaColumns._ID};
String BUCKET_GROUP_BY = " 1) and " + BUCKET_WHERE.toString() + " GROUP BY 1,(2";
cur = context.getContentResolver().query(images, PROJECTION_BUCKET,
BUCKET_GROUP_BY, null, BUCKET_ORDER_BY);
android.database.sqlite.SQLiteException: near "GROUP": syntax error (code 1 SQLITE_ERROR[1])
Here it supposed to obtain list of images with album name, date, count of pictures - one image for each album, so we can create album picker screen without querying all pictures and loop through it to create albums.
Is it possible to group query results with contentResolver since SQL queries stoped work?
(I know that ImageColumns.DATA and "COUNT() AS COUNT" are deprecated too, but this is a question about GROUP BY)
(There is a way to query albums and separately query photo, to obtain photo uri for album cover, but i want to avoid overheads)
Unfortunately Group By is no longer supported in Android 10 and above, neither any aggregated functions such as COUNT. This is by design and there is no workaround.
The solution is what you are actually trying to avoid, which is to query, iterate, and get metrics.
To get you started you can use the next snipped, which will resolve the buckets (albums), and the amount of records in each one.
I haven't added code to resolve the thumbnails, but is easy. You must perform a query for each bucket Id from all the Album instances, and use the image from the first record.
public final class AlbumQuery
{
#NonNull
public static HashMap<String, AlbumQuery.Album> get(#NonNull final Context context)
{
final HashMap<String, AlbumQuery.Album> output = new HashMap<>();
final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
final String[] projection = {MediaStore.Images.Media.BUCKET_DISPLAY_NAME, MediaStore.Images.Media.BUCKET_ID};
try (final Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, null))
{
if ((cursor != null) && (cursor.moveToFirst() == true))
{
final int columnBucketName = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
final int columnBucketId = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_ID);
do
{
final String bucketId = cursor.getString(columnBucketId);
final String bucketName = cursor.getString(columnBucketName);
if (output.containsKey(bucketId) == false)
{
final int count = AlbumQuery.getCount(context, contentUri, bucketId);
final AlbumQuery.Album album = new AlbumQuery.Album(bucketId, bucketName, count);
output.put(bucketId, album);
}
} while (cursor.moveToNext());
}
}
return output;
}
private static int getCount(#NonNull final Context context, #NonNull final Uri contentUri, #NonNull final String bucketId)
{
try (final Cursor cursor = context.getContentResolver().query(contentUri,
null, MediaStore.Images.Media.BUCKET_ID + "=?", new String[]{bucketId}, null))
{
return ((cursor == null) || (cursor.moveToFirst() == false)) ? 0 : cursor.getCount();
}
}
public static final class Album
{
#NonNull
public final String buckedId;
#NonNull
public final String bucketName;
public final int count;
Album(#NonNull final String bucketId, #NonNull final String bucketName, final int count)
{
this.buckedId = bucketId;
this.bucketName = bucketName;
this.count = count;
}
}
}
This is a more efficient(not perfect) way to do that.
I am doing it for videos, but doing so is the same for images to. just change MediaStore.Video.Media.X to MediaStore.Images.Media.X
public class QUtils {
/*created by Nasib June 6, 2020*/
#RequiresApi(api = Build.VERSION_CODES.Q)
public static ArrayList<FolderHolder> loadListOfFolders(Context context) {
ArrayList<FolderHolder> allFolders = new ArrayList<>();//list that we need
HashMap<Long, String> folders = new HashMap<>(); //hashmap to track(no duplicates) folders by using their ids
String[] projection = {MediaStore.Video.Media._ID,
MediaStore.Video.Media.BUCKET_ID,
MediaStore.Video.Media.BUCKET_DISPLAY_NAME,
MediaStore.Video.Media.DATE_ADDED};
ContentResolver CR = context.getContentResolver();
Uri root = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
Cursor c = CR.query(root, projection, null, null, MediaStore.Video.Media.DATE_ADDED + " desc");
if (c != null && c.moveToFirst()) {
int folderIdIndex = c.getColumnIndexOrThrow(MediaStore.Video.Media.BUCKET_ID);
int folderNameIndex = c.getColumnIndexOrThrow(MediaStore.Video.Media.BUCKET_DISPLAY_NAME);
int thumbIdIndex = c.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
int dateAddedIndex = c.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_ADDED);
do {
Long folderId = c.getLong(folderIdIndex);
if (folders.containsKey(folderId) == false) { //proceed only if the folder data has not been inserted already :)
long thumbId = c.getLong(thumbIdIndex);
String folderName = c.getString(folderNameIndex);
String dateAdded = c.getString(dateAddedIndex);
Uri thumbPath = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, thumbId);
folders.put(folderId, folderName);
allFolders.add(new FolderHolder(String.valueOf(thumbPath), folderName, dateAdded));
}
} while (c.moveToNext());
c.close(); //close cursor
folders.clear(); //clear the hashmap becuase it's no more useful
}
return allFolders;
}
}
FolderHolder model class
public class FolderHolder {
private String folderName;
public long dateAdded;
private String thumbnailPath;
public long folderId;
public void setPath(String thumbnailPath) {
this.thumbnailPath = thumbnailPath;
}
public String getthumbnailPath() {
return thumbnailPath;
}
public FolderHolder(long folderId, String thumbnailPath, String folderName, long dateAdded) {
this.folderId = folderId;
this.folderName = folderName;
this.thumbnailPath = thumbnailPath;
this.dateAdded = dateAdded;
}
public String getFolderName() {
return folderName;
}
}
GROUP_BY supporting in case of using Bundle:
val bundle = Bundle().apply {
putString(
ContentResolver.QUERY_ARG_SQL_SORT_ORDER,
"${MediaStore.MediaColumns.DATE_MODIFIED} DESC"
)
putString(
ContentResolver.QUERY_ARG_SQL_GROUP_BY,
MediaStore.Images.ImageColumns.BUCKET_ID
)
}
contentResolver.query(
uri,
arrayOf(
MediaStore.Images.ImageColumns.BUCKET_ID,
MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
MediaStore.Images.ImageColumns.DATE_TAKEN,
MediaStore.Images.ImageColumns.DATA
),
bundle,
null
)
public class Branch
{
[Sortable(OrderBy = "BranchId")]
public long BranchId { get; set; }
public string Name { get; set; }
public string Code { get; set; }
public string Type { get; set; }
}
this is my Model class and I also create a custom attribute
public class SortableAttribute : Attribute
{
public string OrderBy { get; set; }
}
now i create a pagination with orderby descending but this code not working
public static async Task<IPagedList<T>> ToPagedListAsync<T>(this IQueryable<T> source,
GeneralPagingRequest pagingRequest, int indexFrom = 0,
CancellationToken cancellationToken = default(CancellationToken))
{
if (indexFrom > pagingRequest.PageNumber)
{
throw new ArgumentException(
$"indexFrom: {indexFrom} > pageNumber: {pagingRequest.PageNumber}, must indexFrom <= pageNumber");
}
var count = await source.CountAsync(cancellationToken).ConfigureAwait(false);
var items = source.Skip(((pagingRequest.PageNumber - 1) - indexFrom) * pagingRequest.PageSize)
.Take(pagingRequest.PageSize);
var props = typeof(T).GetProperties();
PropertyInfo orderByProperty;
orderByProperty =
props.FirstOrDefault(x=>x.GetCustomAttributes(typeof(SortableAttribute), true).Length != 0);
if (pagingRequest.OrderBy == "desc")
{
items = items.OrderBy(x => orderByProperty.GetValue(x));
}
else
{
items = items.OrderBy(x => orderByProperty.GetValue(x));
}
var result = await items.ToListAsync(cancellationToken).ConfigureAwait(false);
var pagedList = new PagedList<T>
{
PageNumber = pagingRequest.PageNumber,
PageSize = pagingRequest.PageSize,
IndexFrom = indexFrom,
TotalCount = count,
Items = result,
TotalPages = (int) Math.Ceiling(count / (double) pagingRequest.PageSize)
};
return pagedList;
}
but the result variable create exception
.OrderBy() requires a delegate that would tell it HOW to select a key, not the key value itself. So you are looking at some meta-programming here.
Naturally, you will look at building a dynamic LINQ Expression tree that will fetch a property for you:
// your code up above
PropertyInfo orderByProperty = props.FirstOrDefault(x => x.GetCustomAttributes(typeof(SortableAttribute), true).Length != 0);
var p = Expression.Parameter(typeof(T), "x"); // you define your delegate parameter here
var accessor = Expression.Property(p, orderByProperty.GetMethod); // this basically becomes your `x => x.BranchId` construct
var predicate = Expression.Lambda(accessor, p).Compile(); // here's our problem: as we don't know resulting type at compile time we can't go `Expression.Lambda<T, long>(accessor, p)` here
if (pagingRequest.OrderBy == "desc")
{
items = items.OrderByDescending(x => predicate(x)); // passing a Delegate here will not work as OrderBy requires Func<T, TKey>
}
else
{
items = items.OrderBy(x => predicate(x)); // passing a Delegate here will not work as OrderBy requires Func<T, TKey>
}
var result = await items.ToListAsync(cancellationToken).ConfigureAwait(false);
// your code down below
Problem with the above code - you don't know TKey upfront. Therefore we will have to go a level deeper and build the whole items.OrderBy(x => x.BranchId) expression dynamically. The biggest leap of faith here will be the fact the OrderBy is an extension method and it actually resides on IQueryable type. After you've got the generic method reference, you will need to build a specific delegate type when you know your property type. So your method becomes something like this:
public static class ExtToPagedListAsync
{
private static readonly MethodInfo OrderByMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "OrderBy" && method.GetParameters().Length == 2); // you need your method reference, might as well find it once
private static readonly MethodInfo OrderByDescendingMethod = typeof(Queryable).GetMethods().Single(method => method.Name == "OrderByDescending" && method.GetParameters().Length == 2); // you need your method reference, might as well find it once
public static async Task<IPagedList<T>> ToPagedListAsync<T>(this IQueryable<T> source, GeneralPagingRequest pagingRequest, int indexFrom = 0, CancellationToken cancellationToken = default(CancellationToken))
{
if (indexFrom > pagingRequest.PageNumber)
{
throw new ArgumentException(
$"indexFrom: {indexFrom} > pageNumber: {pagingRequest.PageNumber}, must indexFrom <= pageNumber");
}
var count = await source.CountAsync(cancellationToken).ConfigureAwait(false);
var items = source.Skip(((pagingRequest.PageNumber - 1) - indexFrom) * pagingRequest.PageSize)
.Take(pagingRequest.PageSize);
var props = typeof(T).GetProperties();
PropertyInfo orderByProperty = props.FirstOrDefault(x => x.GetCustomAttributes(typeof(SortableAttribute), true).Length != 0);
var p = Expression.Parameter(typeof(T), "x");
var accessor = Expression.Property(p, orderByProperty.GetMethod);
var predicate = Expression.Lambda(accessor, p); // notice, we're not yet compiling the predicate. we still want an Expression here
// grab the correct method depending on your condition
MethodInfo genericMethod = (pagingRequest.OrderBy == "desc") ? OrderByDescendingMethod.MakeGenericMethod(typeof(T), orderByProperty.PropertyType)
:OrderByMethod.MakeGenericMethod(typeof(T), orderByProperty.PropertyType);
object ret = genericMethod.Invoke(null, new object[] { items, predicate });
items = (IQueryable<T>)ret; // finally cast it back to Queryable with your known T
var result = await items.ToListAsync(cancellationToken).ConfigureAwait(false);
var pagedList = new PagedList<T>
{
PageNumber = pagingRequest.PageNumber,
PageSize = pagingRequest.PageSize,
IndexFrom = indexFrom,
TotalCount = count,
Items = result,
TotalPages = (int)Math.Ceiling(count / (double)pagingRequest.PageSize)
};
return pagedList;
}
}
I must disclose I did get some inspiration from this answer here, so do check it out for further reading.
i am developing a smartGWt application that needs to filter list grid content by date and by other staff, every thing is working correctly except the date filtration, this is how i am defining the date fields :
registeredDate = new DataSourceDateField("registrationDate", voc.registeredDate());
registeredDate.setRequired(true);
verificationDate = new DataSourceDateField("lastVerificationDate", voc.verificationDate());
verificationDate.setRequired(true);
the same as every other field
this is how i fill records :
registeredUsersRecords = new ListGridRecord[registeredUsers.length()];
ListGridRecord record = new ListGridRecord();
record.setAttribute(ID, user.getId());
record.setAttribute("firstName", user.getFirstName());
record.setAttribute("lastName", user.getLastName());
record.setAttribute("email", user.getEmail());
record.setAttribute("userMainType", type);
record.setAttribute("isActivated", (user.isActivated())? voc.active(): voc.inActive());
record.setAttribute("country", user.getSelectedCountry().getValue());
record.setAttribute("companyName", user.getCompanyName());
record.setAttribute("registrationDate", user.getRegistrationDate());
record.setAttribute("lastVerificationDate", user.getVerificationDate());
registeredUsersRecords[i] = record;
and then i put them into datasource :
DataSource ds = new DataSource();
ds.setClientOnly(true);
ds.setFields(fName, lName, email, type,typeDetails, status, country, companyName, registeredDate,verificationDate);
for(int i = 0; i< registeredUsersRecords.length; i++){
ds.addData(registeredUsersRecords[i]);
}
registeredUsersListGrid.setDataSource(ds);
registeredUsersListGrid.fetchData();
You have not shared a complete code.
Still I am trying to provide you a sample code. Please have a look.
public class SmartGWTProject implements EntryPoint {
public void onModuleLoad() {
class User {
private int id;
private String firstName;
private Date registrationDate;
public User(int id, String firstName, Date registrationDate) {
this.id = id;
this.firstName = firstName;
this.registrationDate = registrationDate;
}
public int getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public Date getRegistrationDate() {
return registrationDate;
}
}
DateTimeFormat format = DateTimeFormat.getFormat("MM/dd/yyyy");
User[] registeredUsers = new User[] { new User(1, "a", format.parse("01/20/2014")),
new User(2, "b", format.parse("05/20/2013")),
new User(3, "c", format.parse("02/20/2014")) };
ListGridRecord[] registeredUsersRecords = new ListGridRecord[registeredUsers.length];
for (int i = 0; i < registeredUsers.length; i++) {
User user = registeredUsers[i];
ListGridRecord record = new ListGridRecord();
record.setAttribute("id", user.getId());
record.setAttribute("firstName", user.getFirstName());
record.setAttribute("registrationDate", user.getRegistrationDate());
registeredUsersRecords[i] = record;
}
DataSourceDateField registeredDate = new DataSourceDateField("registrationDate", "Date");
DataSourceTextField firstName = new DataSourceTextField("firstName", "Name");
DataSourceIntegerField id = new DataSourceIntegerField("id", "ID");
id.setRequired(true);
id.setPrimaryKey(true);
id.setHidden(true);
DataSource ds = new DataSource();
ds.setClientOnly(true);
ds.setFields(id, firstName, registeredDate);
for (int i = 0; i < registeredUsersRecords.length; i++) {
ds.addData(registeredUsersRecords[i]);
}
ListGrid registeredUsersListGrid = new ListGrid();
registeredUsersListGrid.setDataSource(ds);
registeredUsersListGrid.fetchData();
registeredUsersListGrid.draw();
}
}
We are using org.mongodb.morphia to convert objects BasicDBObjects before persistence. One issue encountered is that in some cases the object to convert contains an empty HashMap whose size is 0, after conversion, the HashMap is converted to null. So NullPointerException throw in later accessing. I want to ask experts for help, Is there any way to avoid this? I mean, after conversion, it's still an HashMap with size 0.
Part of the class to be converted:
public class ProjectServiceAdapterConfig {
#NotNull
private String serviceAdapterId;
#NotNull
private String projectId;
#Embedded
#Flatten
private Map<String, Map<String, String>> connections = new HashMap<>();
//...... setter and getter skipped here
}
code for conversion:
// create a mapper with default MapperOptions
private Mapper createMapper() {
return new Mapper();
}
ReplaceableItem objectToItem(final ProjectServiceAdapterConfig obj) {
final Mapper mapper = createMapper();
final MappedClass mc = mapper.getMappedClass(obj.getClass());
final Map<String, Object> map = mapper.toDBObject(obj).toMap();
}
the obj is created in other place. After some debug, I found that, the obj contains an empty Map(following data copied from IntelliJ IDEA debugger):
connections = {java.util.LinkedHashMap#8890} size = 1
[0] = {java.util.LinkedHashMap$Entry#8894}"accounts" -> size = 0
key: java.lang.String = {java.lang.String#8895}"accounts"
value: java.util.LinkedHashMap = {java.util.LinkedHashMap#8896} size = 0
and the one after converted:
[2] = {java.util.LinkedHashMap$Entry#8910}"connections" -> size = 1
key: java.lang.String = {java.lang.String#8911}"connections"
value: com.mongodb.BasicDBObject = {com.mongodb.BasicDBObject#8912} size = 1
[0] = {java.util.LinkedHashMap$Entry#8923}"accounts" -> null
key: java.lang.String = {java.lang.String#8895}"accounts"
value: = null
As you can see , it's converted to null which we try to avoid.
Thanks
Before you call morphia.mapPackage(), do this:
morphia.getMapper().getOptions().storeEmpties = true;
That should map back probably to an empty map for you.
I assume I cannot avoid it without customizing the MapOfValuesConverter. See from the source code that the empty map will be always converted to null:
#Override
public Object encode(Object value, MappedField mf) {
if (value == null)
return null
Map<Object, Object> map = (Map<Object, Object>) value;
if ((map != null) && (map.size() > 0)) {
Map mapForDb = new HashMap();
for (Map.Entry<Object, Object> entry : map.entrySet()) {
String strKey = converters.encode(entry.getKey()).toString();
mapForDb.put(strKey, converters.encode(entry.getValue()));
}
return mapForDb;
}
return null;
}
In case morphia.getMapper().getOptions().setStoreEmpties(true); doesn't work for you another solution would be to use the #PostLoad annotation to check whether you have a null collection and create an empty one if necessary.
import java.util.*;
import org.mongodb.morphia.annotations.*;
import org.bson.types.ObjectId;
#Entity
public class Model {
#Id
private ObjectId id;
private Map<String, String> map;
protected Model() {}
public Model(HashMap<String, String> map) {
super();
setMap(map);
}
public void setMap(HashMap<String, String> map) {
this.map = map;
checkForNullMap();
}
#PostLoad
private void checkForNullMap() {
if (map == null) {
map = new HashMap<String, String>();
}
}
}
hii i want clickable image map in gwt project...i have created a simple XY map but now i want clickable imagemap...please help me for that
i just want to create a chart where mouse over effect take place....
here is my code
public class ChartGenerator extends ApplicationFrame{
private List<String> trainTypeArray = new ArrayList<String>();
private String lineType;
private List<Long> startTimeOfTrain = new ArrayList<Long>();
private List<Boolean> labelVisibility = new ArrayList<Boolean>();
private List<Integer> stationDistance= new ArrayList<Integer>();
private List<String> lineColorArray = new ArrayList<String>();
private List<String> lineShadeArray = new ArrayList<String>();
private List<String> stationNames = new ArrayList<String>();
private List<String> trainArray = new ArrayList<String>();
private JFreeChart chart =null;
private int startTimeLong;
private int endTimeLong;
private String timezone;
private boolean prediction;
public ChartGenerator(String title, Date dt, String startTime, String endTime, String serviceDirection, String lineType, int delay, boolean prediction) throws BombardierBaseException, BombardierException {
/*super(title)*/;
String[] startSplit = startTime.split(":");
String[] endTimeSplit = endTime.split(":");
this.timezone = startTime +"-"+endTime;
startTimeLong = Integer.parseInt(startSplit[0])*60*60*1000+Integer.parseInt(startSplit[1])*60*1000;
endTimeLong = Integer.parseInt(endTimeSplit[0])*60*60*1000+Integer.parseInt(endTimeSplit[1])*60*1000;
endTimeLong = endTimeLong+(60*1000);
this.prediction = prediction;
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy");
String dtOfJourney = "'" +sdf.format(dt)+"'";
this.lineType = lineType;
System.out.println("Create data-set now");
final XYDataset dataset = createDataset(dtOfJourney, startTimeLong,endTimeLong,serviceDirection);
chart= createChart(dataset, dtOfJourney, serviceDirection);
}
public int getStartTimeLong() {
return startTimeLong;
}
public void setStartTimeLong(int startTimeLong) {
this.startTimeLong = startTimeLong;
}
public int getEndTimeLong() {
return endTimeLong;
}
public JFreeChart getChart(){
return chart;
}
public BufferedImage getBufferedImage(int width, int height){
ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection());
return this.chart.createBufferedImage(width,height, info);
}
private double getStationDistion(String name){
return InitializeProperties.getStationDistance(name);
}
private XYDataset createDataset(String dtOfJourney, long startTime,long endTime,String serviceDirection) throws BombardierBaseException {
ResultSet resultSet =null;
Statement readstatement = null;
Connection con = null;
System.out.println("Entering get Connection now");
System.out.flush();
try{
System.out.println("Getting connection");
System.out.flush();
con = InitializeProperties.getConnection();
System.out.println("Connection initialized");
System.out.flush();
readstatement= con.createStatement();
final XYSeriesCollection dataset1 = new XYSeriesCollection();
String lineTypeFilter = "";
if(!this.lineType.equals("A")){
if(lineType.equals("L")){
lineTypeFilter = "and lt.act_lineType like ' '";
}else{
lineTypeFilter = "and lt.act_lineType like '" + this.lineType + "'";
}
}
int n = 0;
String serviceDirectionClause = "";