Method setSerial(boolean serial) gone in Liferay 7 - liferay

I am working on a code migration project from Liferay 6.2 to Liferay 7.1. In Liferay 6.2 there is a class BaseBackgroundTaskExecutor containing a method setSerial(boolean serial). However in Liferay 7.1 the method is gone and I cannot find any replacement for it.
Is anybody here familiar with my issue or Liferay in general and can provide me with some guidance?
Greetings,
Michael

Comparing the two branches (6.2.x & 7.1.x), it looks like it has been replaced with setIsolationLevel(int). Its Interface's method isSerial() is still there, but its implementation changed:
#Override
public boolean isSerial() {
if (_isolationLevel == BackgroundTaskConstants.ISOLATION_LEVEL_NOT_ISOLATED) {
return false;
}
return true;
}
You could just call setIsolationLevel(BackgroundTaskConstants.ISOLATION_LEVEL_NOT_ISOLATED) instead of setSerial(false). Since ISOLATION_LEVEL_NOT_ISOLATED's value is 4, any value but 4 would make isSerial() return true.
Or, if you really want to, you could also just overwrite the isSerial() method and let it either return true or false.
However, you should take a look at the BackgroundTaskLockHelperUtil implementation. Especially it's method getLockKey(BackgroundTask):
protected static String getLockKey(BackgroundTask backgroundTask) {
BackgroundTaskExecutor backgroundTaskExecutor =
BackgroundTaskExecutorRegistryUtil.getBackgroundTaskExecutor(
backgroundTask.getTaskExecutorClassName());
String lockKey = StringPool.BLANK;
if (backgroundTaskExecutor.getIsolationLevel() ==
BackgroundTaskConstants.ISOLATION_LEVEL_CLASS) {
lockKey = backgroundTask.getTaskExecutorClassName();
}
else if (backgroundTaskExecutor.getIsolationLevel() ==
BackgroundTaskConstants.ISOLATION_LEVEL_COMPANY) {
lockKey =
backgroundTask.getTaskExecutorClassName() + StringPool.POUND +
backgroundTask.getCompanyId();
}
else if (backgroundTaskExecutor.getIsolationLevel() ==
BackgroundTaskConstants.ISOLATION_LEVEL_CUSTOM) {
lockKey = backgroundTaskExecutor.generateLockKey(backgroundTask);
}
else if (backgroundTaskExecutor.getIsolationLevel() ==
BackgroundTaskConstants.ISOLATION_LEVEL_GROUP) {
lockKey =
backgroundTask.getTaskExecutorClassName() + StringPool.POUND +
backgroundTask.getGroupId();
}
else if (backgroundTaskExecutor.getIsolationLevel() ==
BackgroundTaskConstants.ISOLATION_LEVEL_TASK_NAME) {
lockKey =
backgroundTask.getTaskExecutorClassName() + StringPool.POUND +
backgroundTask.getName();
}
else {
lockKey =
backgroundTask.getTaskExecutorClassName() + StringPool.POUND +
backgroundTaskExecutor.getIsolationLevel();
}
return lockKey;
}
So based on your "Isolation Level", a specific lock will be acquired, so you should first consider if you want to have multiple instances of your BackgroundTaskExecutor run parallel (isSerial() should return false) or not. If not, think about which Isolation Level fits best and use it.

Related

Desperately need Xamarin.IOS modal MessageBox like popup

Coding in Xamarin IOS. I have a drop down list type popup, where, if The end user types in a new value, I want to ask a yes/no question: Do You want to add a new row?
The control is inside a UIStackView, which is inside a container UIView, which is in turn inside another which is presented via segue. Xamarin demanded a UIPopoverController, which I implemented. Here is The code I have so far:
using System.Threading.Tasks;
using Foundation;
using UIKit;
namespace PTPED_Engine
{
public enum MessagePopupType
{
YesNo = 1,
OKCancel = 2,
OKOnly = 3
}
public enum PopupResultType
{
OK = 1,
Cancel = 2,
Yes = 3,
No = 4
}
public static class AlertPopups
{
static NSObject nsObject;
public static void Initialize(NSObject nsObject)
{
AlertPopups.nsObject = nsObject;
}
public static Task<PopupResultType> AskUser(UIViewController parent, UIView V, string strTitle, string strMsg, MessagePopupType mpt)
{
using (UIPopoverController pc = new UIPopoverController(parent))
{
// pc.ContentViewController
// method to show an OK/Cancel dialog box and return true for OK, or false for cancel
var taskCompletionSource = new TaskCompletionSource<PopupResultType>();
var alert = UIAlertController.Create(strTitle, strMsg, UIAlertControllerStyle.ActionSheet);
// set up button event handlers
if (mpt == MessagePopupType.OKCancel)
{
alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.OK)));
alert.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.Cancel)));
}
if (mpt == MessagePopupType.YesNo)
{
alert.AddAction(UIAlertAction.Create("Yes", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.Yes)));
alert.AddAction(UIAlertAction.Create("No", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.No)));
}
if (mpt == MessagePopupType.OKOnly)
{
alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.OK)));
}
// show it
nsObject.InvokeOnMainThread(() =>
{
pc.PresentFromRect(V.Bounds, V, UIPopoverArrowDirection.Any, true);
});
return taskCompletionSource.Task;
}
}
}
}
and I invoke it as follows:
LookupCombo.Completed += async (object sender, CompletedEventArgs e) =>
{
C1AutoComplete AC = (C1AutoComplete)sender;
if (AC.Text.Trim() != "")
{
string sColName = AC.AccessibilityIdentifier.Trim();
var ValuesVC = (List<Lookupcombo_Entry>)AC.ItemsSource;
var IsThisAHit = from Lookupcombo_Entry in ValuesVC
where Lookupcombo_Entry.sDispVal.ToUpper().Trim() == e.value.ToUpper().Trim()
select Lookupcombo_Entry.sMapVal;
if (!IsThisAHit.Any())
{
string sTitle = "";
string sFull = _RM.GetString(sColName);
if (sFull == null) { sFull = "???-" + sColName.Trim(); }
sTitle = " Add New " + sFull.Trim() + "?";
string sPPrompt = "Do you want to add a new " + sFull.Trim() + " named " + AC.Text.Trim() + " to the Database?";
var popupResult = await AlertPopups.AskUser(CurrentViewController(), V, sTitle, sPPrompt, MessagePopupType.YesNo);
}
}
};
CurrentViewController is defined like this:
private UIViewController CurrentViewController()
{
var window = UIApplication.SharedApplication.KeyWindow;
var vc = window.RootViewController;
while (vc.PresentedViewController != null)
{
vc = vc.PresentedViewController;
}
return vc;
}
This does nothing. It hangs The user interface.
This should be built in, but it is only built in in Xamarin.Forms, which I do not want to use.
I have no problem in doing this stuff with an await, but this is simply not working. Can anyone help?
Thanks!
You can just use the ACR UserDialogs library:
https://github.com/aritchie/userdialogs
This is a solution I provided a few years ago, I think it is an ugly hack, compared to your elegant approach. You did not say what part does not work exactly, that might help spot the problem.
Here is my solution from a few years back:
iphone UIAlertView Modal

lotus.domino.local.Item cannot be cast to lotus.domino.RichTextItem

I try to put a file into a richtext but it crashes !
In my first code, I try to use directly "getFirstItem", in first time it was ok but now i try to use it again and it crashed.
In second time i pass with an object and it find my obj doesn't an richtextItem (instanceof) ???
I don't understand.
I have the message : "lotus.domino.local.Item cannot be cast to lotus.domino.RichTextItem" ?
Could you help me ?
public void copieFichierDansRichText(String idDocument, String nomRti, File file,
String nameFichier, String chemin) throws NotesException {
lotus.domino.Session session = Utils.getSession();
lotus.domino.Database db = session.getCurrentDatabase();
lotus.domino.Document monDoc = db.getDocumentByUNID(idDocument);
lotus.domino.RichTextItem rtiNew = null;
try {
try {
if (monDoc != null) {
// if (monDoc.getFirstItem(nomRti) != null) {
// rtiNew = (lotus.domino.RichTextItem)
// monDoc.getFirstItem(nomRti);
// } else {
// rtiNew = (lotus.domino.RichTextItem)
// monDoc.createRichTextItem(nomRti);
// }
Object obj = null;
if (monDoc.getFirstItem(nomRti) != null) {
obj = monDoc.getFirstItem(nomRti);
if (obj instanceof lotus.domino.RichTextItem) {
rtiNew = (lotus.domino.RichTextItem) obj;
}
} else {
obj = monDoc.createRichTextItem(nomRti);
if (obj instanceof lotus.domino.RichTextItem) {
rtiNew = (lotus.domino.RichTextItem) obj;
}
}
PieceJointe pieceJointe = new PieceJointe();
pieceJointe = buildPieceJointe(file, nameFichier, chemin);
rtiNew.embedObject(EmbeddedObject.EMBED_ATTACHMENT, "", pieceJointe.getChemin()
+ pieceJointe.getNomPiece(), pieceJointe.getNomPiece());
monDoc.computeWithForm(true, false);
monDoc.save(true);
}
} finally {
rtiNew.recycle();
monDoc.recycle();
db.recycle();
session.recycle();
}
} catch (Exception e) {
e.printStackTrace();
}
}
EDIT : I try to modify my code with yours advices but the items never considerate as richtextitem. It is my problem. I don't understand why, because in my field it is a richtext ! For it, the item can't do :
rtiNew = (lotus.domino.RichTextItem) item1;
because item1 not be a richtext !!!
I was trying to take all the fields and pass in the item one by one, and it never go to the obj instance of lotus.domini.RichTextItem....
Vector items = doc.getItems();
for (int i=0; i<items.size(); i++) {
// get next element from the Vector (returns java.lang.Object)
Object obj = items.elementAt(i);
// is the item a RichTextItem?
if (obj instanceof RichTextItem) {
// yes it is - cast it as such // it never go here !!
rt = (RichTextItem)obj;
} else {
// nope - cast it as an Item
item = (Item)obj;
}
}
A couple of things. First of all I would set up a util class method to handle the object recycling in a neater way:
public enum DominoUtil {
;
public static void recycle(Base... bases) {
for (Base base : bases) {
if (base != null) {
try {
base.recycle();
} catch (Exception e) {
// Do nothing
}
}
}
}
}
Secondly I would remove the reduntants try/catch blocks and simplify it like this:
private void copieFichierDansRichText(String idDocument, String nomRti, File file,
String nameFichier, String chemin) {
Session session = DominoUtils.getCurrentSession();
Database db = session.getCurrentDatabase();
Document monDoc = null;
try {
monDoc = db.getDocumentByUNID(idDocument);
Item item = monDoc.getFirstItem(nomRti);
if (item == null) {
item = monDoc.createRichTextItem(nomRti);
} else if (item.getType() != Item.RICHTEXT) {
// The item is not a rich text item
// What are you going to do now?
}
RichTextItem rtItem = (RichTextItem) item;
PieceJointe pieceJointe = new PieceJointe();
pieceJointe = buildPieceJointe(file, nameFichier, chemin);
rtItem.embedObject(EmbeddedObject.EMBED_ATTACHMENT, "", pieceJointe.getChemin()
+ pieceJointe.getNomPiece(), pieceJointe.getNomPiece());
monDoc.computeWithForm(true, false);
monDoc.save(true);
} catch (NotesException e) {
throw new FacesException(e);
} finally {
DominoUtil.recycle(monDoc);
}
}
Finally, apart from the monDoc, you need not recycle anything else. Actually Session would be automatically recycled and anything beneath with it (so no need to recycle db, let alone the session!, good rule is don't recycle what you didn't instantiate), but it's not bad to keep the habit of keeping an eye on what you instantiate. If it were a loop with many documents you definitively want to do that. If you also worked with many items you would want to recycle them as early as possible. Anyway, considered the scope of the code it's sufficient like this. Obviously you would call DominoUtil.recycle directly from the try block. If you have multiple objects you can recycle them at once possibly by listing them in the reverse order you set them (eg. DominoUtil.recycle(item, doc, view)).
Also, what I think you miss is the check on the item in case it's not a RichTextItem - and therefore can't be cast. I put a comment where I think you should decide what to do before proceeding. If you let it like that and let the code proceed you will have the code throw an error. Always better to catch the lower level exception and re-throw a higher one (you don't want the end user to know more than it is necessary to know). In this case I went for the simplest thing: wrapped NotesException in a FacesException.

Trying to compute a method to call in a Bean

I have a managed bean that returns a number of different properties that describe an application. So it can be called to return the FilePath of a database by calling
appProps[sessionScope.ssApplication].helpFilePath
or
appProps[sessionScope.ssApplication].ruleFilePath
I'm trying to work out a generalized case where I need to call for the file path based on a value in a compositeData variable which can take on any one of 4 different values help/rule/app/main.
I wrote this SSJS and it works but I am wondering if there is a better way to make it work:
var target:String = compositeData.DBSource;
switch (target){
case "app" :
return appProps[sessionScope.ssApplication].appFilePath;
break;
case "help" :
return appProps[sessionScope.ssApplication].helpFilePath;
break;
case "rule" :
return appProps[sessionScope.ssApplication].ruleFilePath;
break;
case "main" :
return appProps[sessionScope.ssApplication].mainFilePath;
break;
}
I can't figure out if there is a way to compute the method by using compositeData.DBSource + "FilePath" . when I try this I get an error that the method does not exist. Using the SSJS code above is not really a problem but it just seems a bit redundant.
You can make a new method in your managed bean that takes target as an argument:
public String getFilePath(String target) {
String returnValue = "";
if (target.equalsIgnoreCase("app")) {
returnValue = this.appFilePath;
} else if (target.equalsIgnoreCase("help")) {
returnValue = this.helpFilePath;
} else if (target.equalsIgnoreCase("rule")) {
returnValue = this.ruleFilePath;
} else if (target.equalsIgnoreCase("main")) {
returnValue = this.mainFilePath;
}
return returnValue;
}
And then call it like this in your SSJS:
appProps[sessionScope.ssApplication].getFilePath(compositeData.DBSource);

using like operator in if operator in C#

I have a textbox for search (that is, textBox1)
A user, for example, enters "aba" in textBox1.
"abandon" puts in datagridiew1.
The user clicks on datagriview1:
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
richTextBox_MWE.Text = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
if ("richTextBox_MWE.Text like '%" + textBox1.Text + "%'")
{
label5.BackColor = Color.Green;
}
}
I want if "abandon" is such as "aba" in textBox1, label5.BackColor becomes Green.
Simple way is use the textBox1(where actually filter content going to change) change event
if(!String.IsNullOrEmpty(richTextBox_MWE.Text) && richTextBox_MWE.Text.Trim().Contains(textBox1.Text.Trim()))
{
label5.BackColor = Color.Green;
}
You want to use some kind of mix of C# and sql :) You can use the String.Contains method to achieve what you want.
if(richTextBox_MWE.Text != null
&& richTextBox_MWE.Text.Contains(textBox1.Text.Trim())
{
...
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
richTextBox_MWE.Text = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
if (!String.IsNullOrEmpty(richTextBox_MWE.Text) && !String.IsNullOrEmpty(textBox1.Text) && richTextBox_MWE.Text.Contains(textBox1.Text.Trim()))
{
label5.BackColor = Color.Green;
}
}
Here the contains will accept the value to be searched.
See snippet from my code. The txtProductCode is a text box that user is filling the product_code for searching in the list view.
string tmpProductCode = txtProductCode.Text.Trim();
string tmpProductCodePattern = "^" + Regex.Escape(tmpProductCode).Replace("%", ".*") + "$";
In my loop of product_code(s) the prodCode will contain the product_code value for each loop.
productCodeClause = false;
if (tmpProductCode.Equals(""))
{
productCodeClause = true;
}
else
{
if (Regex.IsMatch(prodCode, tmpProductCodePattern))
{
productCodeClause = true;
}
}
I hope this will be helpful.

conditional ObservableForProperty

I'm new in WPF trying to use ReactiveUI,
I want to call 3 different method based on property value changed.
so
public int Number
{
set
{
number = val;
if (_number == 1) Call1()
else if (_number == 2) call2()
else if (_number == 3) call3()
}
}
above is working but now I'm trying using ReactiveUI
so what i did
this.ObservableForProperty(x => x._number).Subscribe( => Call1());
is there any way to achieve above?
If you set up your property like this (assuming your class derives from ReactiveObject):
public int Number
{
get
{
return _number;
}
set
{
this.RaiseAndSetIfChanged(ref _number, value);
}
}
Or, you need to get it to fire property changed notifications some other way.
You didn't say if you are observing the property within the class itself or from a different one. For example, is this all occurring in your ViewModel or in your View watching your ViewModel?
If within the ViewModel with the Number property, I would try something along these lines:
this.WhenAnyValue(t => t.Number)
.Subscribe(i =>
{
if (i == 1)
{
Call1();
}
else if (i == 2)
{
Call2();
}
else if (i == 3)
{
Call3();
}
}
);
If you were in your View that had a ViewModel property holding the ViewModel with the Number property I would try:
this.ObservableForProperty(t => t.ViewModel.Number,i => i)
.Subscribe(i =>
{
if (i == 1)
{
Call1();
}
else if (i == 2)
{
Call2();
}
else if (i == 3)
{
Call3();
}
}
);
How about this:
this.WhenAnyValue(x => x.Number)
.Where(x => x == 1)
.Subscribe(Call1);

Resources