How to retrieve filtered value from a stream and use it - java-8

I'm new to Java 8:
I have to convert this piece of java 6 code to java 8 version:
List<String> unvalidnumbers = new ArrayList<>();
StringBuilder content = new StringBuilder();
String str = "current_user"
for (Iterator<String> it = numbers.iterator(); it.hasNext();) {
String number = it.next();
try {
PersIdentifier persIdentifier = this.getPersIdentifierByNumber(number);
if (persIdentifier != null) {
content.append(number).append(";").append(str);
if (StringUtils.equals(persIdentifier.getType(), "R")) {
content.append(";X");
}
if (it.hasNext()) {
content.append("\r\n");
}
}
} catch (BusException e) {
LOGGER.warn("Pers not found", e);
unvalidnumbers.add(number);
}
}
So i wrote this:
numbers.stream().filter((String number) -> {
try {
return this.getPersIdentifierByNumber(number) != null;
} catch (BusinessException e1) {
LOGGER.warn("Pers not found", e1);
return false;
}
}).forEach(number -> contentConstruction.append(number).append(";").append(str));
I know it's missing this part:
if (StringUtils.equals(persIdentifier.getType(), "R")) {
content.append(";X");
}
if (it.hasNext()) {
content.append("\r\n");
}
But i didn't found way to retrieve the corresponding persIdentifier object.
Any idea please

You should use a more functional approach if you use Java 8.
Instead of a forEach, favor collect(). Here Collectors.joining() looks suitable.
Not tested but you should have an overall idea :
String result =
numbers.stream()
.map(number -> new SimpleEntry<String, PersIdentifier>(number, this.getPersIdentifierByNumber(number) )
.filter(entry -> entry.getValue() != null)
.map(entry ->{
final String base = entry.getKey() + ";" + str;
return "R".equals(entry.getValue().getType()) ? base + ";X" : base;
})
.collect(joining("\r\n")); // Or not OS dependent : System.lineSeparator()

Related

Go through sub tags of IsoMsg and get values for jPOS

I have a jPOS project and I want to loop through sub tags of a field to get it's values. I have the following code and I don't know if it does the job:
Map<String, String> subTagMap = new HashMap<>();
ISOMsg champ11 = (ISOMsg)isoMsg.getComponent(11);
int i = 1;
while(i < 15) {
if (champ11 != null) {
ISOTaggedField subtTag = findTag(champ11, (i < 10) ? "0" + i : String.valueOf(i));
if (subtTag != null) {
LOGGER.debug("Champ11x" + i +"trouvé");
subTagMap.put(subtTag.getTag(), subtTag.getValue().toString());
}
}
i++;
}
return subTagMap;
}
private ISOTaggedField findTag(ISOComponent component, String tagName) {
if (component instanceof ISOTaggedField) {
component = ((ISOTaggedField) component).getDelegate();
}
#SuppressWarnings("unchecked")
Map<Integer, Object> children = component.getChildren();
for (Map.Entry<Integer, Object> entry : children.entrySet()) {
if (entry.getValue() instanceof ISOTaggedField) {
ISOTaggedField tag = (ISOTaggedField) entry.getValue();
if (tag.getTag().equals(tagName)) {
return tag;
}
}
}
return null;
}
This should work:
Map<String, String> subTagMap=new HashMap<>();
ISOMsg champ11 = (ISOMsg) isoMsg.getComponent(119);
if (champ != null) {
for (Object v : champ.getChildren().values()) {
if (!(v instanceof ISOTaggedField)) continue;
ISOTaggedField subTag = (ISOTaggedField) v;
subTagMap.put(subTag.getTag(), (String)subTag.getValue());
}
}
return subTagMap;

Action.Picker returns invalid/wrong Uri (How to get path or byte[] from multiple picked gallery img)

I have an forms app where i need to pick "1 to many" images from the phone storage.
For this i use the dependency injection system.
My problem is the somewhere i get an Android.netUri that resolves to a file that do not exist... and to a file name that i have never seen before.
The kicker is that if i pick pictures that was takes within the last couple of hours this code works...
Im am at the end of my hoap, i really hope someone can point me to something that i'm doing wrong.
i start the Picker activity with:
[assembly: Dependency(typeof(ImagePickerService))]
namespace MyApp.Droid
{
public class ImagePickerService : Java.Lang.Object, IImagePickerService
{
public async Task OpenGallery()
{
try
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Storage))
{
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Need Storage permission to access to your photos.", ToastLength.Long).Show();
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Storage });
status = results[Permission.Storage];
}
if (status == PermissionStatus.Granted)
{
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Pick max 20 images", ToastLength.Long).Show();
var imageIntent = new Intent(Intent.ActionPick);
imageIntent.SetType("image/*");
imageIntent.PutExtra(Intent.ExtraAllowMultiple, true);
imageIntent.SetAction(Intent.ActionPick);
CrossCurrentActivity.Current.Activity.StartActivityForResult(Intent.CreateChooser(imageIntent, "Pick pictures"), 100);
}
else if (status != PermissionStatus.Unknown)
{
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Permission Denied. Can not continue, try again.", ToastLength.Long).Show();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Error. Can not continue, try again.", ToastLength.Long).Show();
}
}
}
then in my MainActivity.cs i have the OnActivityResult
I have tried to use the ContentResolver.OpenInputStream to get the image bytes with no luck, so this is commented out atm.
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == OPENGALLERYCODE && resultCode == Result.Ok)
{
List<string> images = new List<string>();
if (data != null)
{
ClipData clipData = data.ClipData;
if (clipData != null)
{
for (int i = 0; i < clipData.ItemCount; i++)
{
ClipData.Item item = clipData.GetItemAt(i);
/*
var stream = ContentResolver.OpenInputStream(item.Uri); //This throws "FileNotFound"
byte[] byteArray;
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
byteArray = memoryStream.ToArray();
stream.Close();
stream = null;
}
stream = ContentResolver.OpenInputStream(item.Uri);
var exif = new ExifInterface(stream);
stream.Close();
*/
Android.Net.Uri uri = item.Uri;
var path = GetActualPathFromFile(uri);
if (path != null)
{
var tmpImgPath = RotateToOriginalDimention(path);
images.Add(tmpImgPath);
}
}
}
else
{
Android.Net.Uri uri = data.Data;
var path = GetActualPathFromFile(uri);
if (path != null)
{
var tmpImgPath = RotateToOriginalDimention(path);
images.Add(tmpImgPath);
}
}
MessagingCenter.Send<App, List<string>>((App)Xamarin.Forms.Application.Current, "ImagesSelected", images);
}
}
}
And the GetActualPathFromFile (also in my MainActivity.cs)
The hole func is below but i hit this part of the code and get at "FileNotFound"
(...)
else if ("content".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
var retval2 = getDataColumn(this, uri, null, null);
if (File.Exists(retval2)) //<----------------------- This returns "false"
{
return retval2;
}
else
{
throw new Exception("file not found " + retval2);
}
}
(...)
The Hole GetActualPathFromFile
private string GetActualPathFromFile(Android.Net.Uri uri)
{
bool isKitKat = Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat;
if (isKitKat && DocumentsContract.IsDocumentUri(this, uri))
{
// ExternalStorageProvider
if (isExternalStorageDocument(uri))
{
string docId = DocumentsContract.GetDocumentId(uri);
char[] chars = { ':' };
string[] split = docId.Split(chars);
string type = split[0];
if ("primary".Equals(type, StringComparison.OrdinalIgnoreCase))
{
var retval = Android.OS.Environment.ExternalStorageDirectory + "/" + split[1];
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri))
{
string id = DocumentsContract.GetDocumentId(uri);
Android.Net.Uri contentUri = ContentUris.WithAppendedId(
Android.Net.Uri.Parse("content://downloads/public_downloads"), long.Parse(id));
//System.Diagnostics.Debug.WriteLine(contentUri.ToString());
var retval = getDataColumn(this, contentUri, null, null);
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
// MediaProvider
else if (isMediaDocument(uri))
{
String docId = DocumentsContract.GetDocumentId(uri);
char[] chars = { ':' };
String[] split = docId.Split(chars);
String type = split[0];
Android.Net.Uri contentUri = null;
if ("image".Equals(type))
{
contentUri = MediaStore.Images.Media.ExternalContentUri;
}
else if ("video".Equals(type))
{
contentUri = MediaStore.Video.Media.ExternalContentUri;
}
else if ("audio".Equals(type))
{
contentUri = MediaStore.Audio.Media.ExternalContentUri;
}
String selection = "_id=?";
String[] selectionArgs = new String[]
{
split[1]
};
var retval = getDataColumn(this, contentUri, selection, selectionArgs);
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
}
// MediaStore (and general)
else if ("content".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
// Return the remote address
if (isGooglePhotosUri(uri))
{
var retval = uri.LastPathSegment;
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
var retval2 = getDataColumn(this, uri, null, null);
if (File.Exists(retval2))
{
return retval2;
}
else
{
throw new Exception("file not found " + retval2);
}
}
// File
else if ("file".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
var retval = uri.Path;
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
throw new Exception("file not found ");
}
public static String getDataColumn(Context context, Android.Net.Uri uri, String selection, String[] selectionArgs)
{
ICursor cursor = null;
String column = "_data";
String[] projection =
{
column
};
try
{
cursor = context.ContentResolver.Query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.MoveToFirst())
{
int index = cursor.GetColumnIndexOrThrow(column);
return cursor.GetString(index);
}
}
finally
{
if (cursor != null)
cursor.Close();
}
return null;
}
//Whether the Uri authority is ExternalStorageProvider.
public static bool isExternalStorageDocument(Android.Net.Uri uri)
{
return "com.android.externalstorage.documents".Equals(uri.Authority);
}
//Whether the Uri authority is DownloadsProvider.
public static bool isDownloadsDocument(Android.Net.Uri uri)
{
return "com.android.providers.downloads.documents".Equals(uri.Authority);
}
//Whether the Uri authority is MediaProvider.
public static bool isMediaDocument(Android.Net.Uri uri)
{
return "com.android.providers.media.documents".Equals(uri.Authority);
}
//Whether the Uri authority is Google Photos.
public static bool isGooglePhotosUri(Android.Net.Uri uri)
{
return "com.google.android.apps.photos.content".Equals(uri.Authority);
}
Found out that the real problem was that Google Photos App was not updating and was still showing images that were deleted.
After 2x reboot of the phone, Google Photos app finally updated.
So this looks more like a cache problem with Google Foto than a xamarin problem.

redisTemplate ValueOperations increment get null

First of all, I have to say that key exists in redis,
This key is a self-increasing sequence,
But sometimes getting this key is null.
I used spring-boot: 2.0.4.0.release
My expectation is to get a self-increment of 1 at a time to generate the order number
Could you advice a solution for my scenario? Thanks!
#Override
#Transactional(rollbackFor = Exception.class)
public boolean paymentBatchMeter(UserDescriptor user, String areaCode, String newPrice) {
List<Meter> meters = meterService.findAllByFilterAndAreaCode(null, areaCode, user);
if (meters != null && meters.size() > 0) {
List<TaskValue> taskValueList = new ArrayList<>();
meters.forEach(meter -> {
if (meter.getState() == 1) {
Task task = new Task();
task.setCode(meter.getCode());
TaskValue taskValue = new TaskValue();
taskValue.setId(task.getId());
taskValue.setMeterType(meter.getMeterDicCode());
taskValue.setCode(meter.getCode());
Long orderIndex = redisTemplate.opsForValue().increment("athena:order:index", 1);
if (orderIndex == null) {
throw new IllegalStateException("error!");
}
taskValueList.add(taskValue);
Order order = new Order();
order.setCustomerId(meter.getCustomerId());
order.setCode(orderIndex.toString());
order.setCreateTime(new Date());
order.setMeterId(meter.getId());
order.setState(0);
order.setRechargeMoney(new BigDecimal(newPrice));
List<DicProjectItem> dicProjectItems = dicProjectItemMapper.getDicProjectItemAll("D10015", 1);
String dicProjectItemId = dicProjectItems.stream().filter(p -> "002".equals(p.getCode())).collect(Collectors.toList()).get(0).getId();
order.setRechargeWayDicId(dicProjectItemId);
order.setRechargeState(1);
order.setTaskId(task.getId());
order.setOperatorId(user.getId());
}
});
redisTemplate.setEnableTransactionSupport(true);
taskValueList.forEach(taskValue -> {
if ("004".equals(taskValue.getMeterType())) {
redisTemplate.convertAndSend(TOPIC, taskValue.getCode());
redisTemplate.opsForList().rightPush("athena:concentrator:meter:task:" + taskValue.getCode(), JSON.toJSONString(taskValue));
} else {
redisTemplate.opsForList().rightPush("athena:meter:task:" + taskValue.getCode(), JSON.toJSONString(taskValue));
}
});
redisTemplate.setEnableTransactionSupport(false);
return true;
}
return false;
}

how to wait for ParseCloud.callFunctionInBackgroud

I have a Utility function which I use to check if user has done few operations or not. If not, Then I need to send the results back to MainActivity.
public static boolean checkUserIsDone(String receiverPhoneNumber, String senderNumber ) {
hasApp = false;
HashMap<String, Object> parseParams = new HashMap<>();
parseParams.put("phoneNumber", receiverPhoneNumber);
parseParams.put("senderNumber", senderNumber);
ParseCloud.callFunctionInBackground("GetUserByPhoneNumber", parseParams, new FunctionCallback<String>() {
public void done(String result, ParseException e) {
if (e == null && result.equals("success")) {
hasApp = true;
} else {
hasApp = false;
Log.e("Error: ", e.getMessage());
}
}
});
return hasApp;
}

Transferring assets : Error code 4005 ASSET_UNAVAILABLE

This is driving me crazy. I wrote a code quite a while ago that was working, and opened it again and it happens that I am not able to transfer my assets from the mobile to the wearable device.
public Bitmap loadBitmapFromAsset(Asset asset) {
if (asset == null) {
throw new IllegalArgumentException("Asset must be non-null");
}
// convert asset into a file descriptor and block until it's ready
Log.d(TAG, "api client" + mApiClient);
DataApi.GetFdForAssetResult result = Wearable.DataApi.getFdForAsset(mApiClient, asset).await();
if (result == null) {
Log.w(TAG, "getFdForAsset returned null");
return null;
}
if (result.getStatus().isSuccess()) {
Log.d(TAG, "success");
} else {
Log.d(TAG, result.getStatus().getStatusCode() + ":" + result.getStatus().getStatusMessage());
}
InputStream assetInputStream = result.getInputStream();
if (assetInputStream == null) {
Log.w(TAG, "Requested an unknown Asset.");
return null;
}
// decode the stream into a bitmap
return BitmapFactory.decodeStream(assetInputStream);
}
And this is the code from which I call the loadBitmapFrom Asset method.
DataMap dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
ArrayList<DataMap> dataMaps = dataMap.getDataMapArrayList("dataMaps");
ArrayList<String> names = new ArrayList<>();
ArrayList<String> permalinks = new ArrayList<>();
ArrayList<Asset> images = new ArrayList<>();
for (int i = 0 ; i < dataMaps.size() ; i++) {
Log.d(TAG, dataMaps.get(i).getString("name"));
names.add(dataMaps.get(i).getString("name"));
permalinks.add(dataMaps.get(i).getString("permalink"));
images.add(dataMaps.get(i).getAsset("image"));
}
editor.putInt("my_selection_size", names.size());
for (int i=0; i <names.size() ; i++) {
editor.putString("my_selection_name_" + i, names.get(i));
editor.putString("my_selection_permalink_" + i, permalinks.get(i));
Log.d(TAG, "asset number " + i + " " + images.get(i));
Bitmap bitmap = loadBitmapFromAsset(images.get(i));
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
editor.putString("my_selection_image_" + i, encoded);
}
And on the mobile side :
private void sendData(PutDataMapRequest dataMap) {
PutDataRequest request = dataMap.asPutDataRequest();
request.setUrgent();
com.google.android.gms.common.api.PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi.putDataItem(mApiClient, request);
pendingResult.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
#Override
public void onResult(DataApi.DataItemResult dataItemResult) {
com.orange.radio.horizon.tools.Log.d(TAG, "api client : " + mApiClient);
if (dataItemResult.getStatus().isSuccess()) {
com.orange.radio.horizon.tools.Log.d(TAG, "message successfully sent");
} else if (dataItemResult.getStatus().isInterrupted()) {
com.orange.radio.horizon.tools.Log.e(TAG, "couldn't send data to watch (interrupted)");
} else if (dataItemResult.getStatus().isCanceled()) {
com.orange.radio.horizon.tools.Log.e(TAG, "couldn't send data to watch (canceled)");
}
}
});
Log.d(TAG, "Sending data to android wear");
}
class ConfigTask extends AsyncTask<String, Void, String> {
ArrayList<WatchData> mitems;
int mType;
public ConfigTask(ArrayList<WatchData> items, int type)
{
mitems = items;
mType = type;
}
protected String doInBackground(String... str)
{
DataMap dataMap;
ArrayList<DataMap> dataMaps = new ArrayList<>();
Bitmap bitmap = null;
for (int i = 0 ; i < mitems.size() ; i++) {
dataMap = new DataMap();
URL url = null;
try {
url = new URL(mitems.get(i).mUrlSmallLogo);
Log.d(TAG, "url : " + url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
Asset asset = createAssetFromBitmap(bitmap);
dataMap.putAsset("image", asset);
dataMap.putString("name", mitems.get(i).mName);
dataMap.putString("permalink", mitems.get(i).mPermalink);
dataMaps.add(dataMap);
}
PutDataMapRequest request = null;
switch (mType) {
case 0 :
request = PutDataMapRequest.create(SELECTION_PATH);
break;
case 1 :
request = PutDataMapRequest.create(RADIOS_PATH);
break;
case 2 :
request = PutDataMapRequest.create(PODCASTS_PATH);
break;
}
request.getDataMap().putDataMapArrayList("dataMaps", dataMaps);
request.getDataMap().putString("", "" + System.currentTimeMillis()); //random data to refresh
Log.d(TAG, "last bitmap : " + bitmap);
Log.d(TAG, "===============================SENDING THE DATAMAP ARRAYLIST==================================");
sendData(request);
return "h";
}
protected void onPostExecute(String name)
{
}
}
When executing that code, I see the following error happening :
02-02 14:47:59.586 7585-7601/? D/WearMessageListenerService﹕ 4005:ASSET_UNAVAILABLE
I saw that related thread Why does Wearable.DataApi.getFdForAsset produce a result with status 4005 (Asset Unavailable)? but it didn't really help me
I recently had the same problem... I solved it by updating the Google play service, and adding the same signing configuration to both the app and the wearable module. If it doesn't work on the first build go to "invalidate caches / restart" in files and it should work.

Resources