How to free a session variable in Liferay? - liferay

In Liferay, I'm using session variables for InterPortlet Communication.
PortletSession psession = request.getPortletSession();
String userId = (String) psession.getAttribute("userId", PortletSession.APPLICATION_SCOPE);
After use of this variable, I want to destroy it.
How to destroy, scrap the session variables in liferay?

Use removeAttribute method of PortletSession. It will remove attribute from session.
In your case psession.removeAttribute("userId");
This is applicable to request and session attributes also.

Related

How to make a variable that is accessible and changeable by all files in project

Say I wanted to have a string containing the user's name, and I wanted to be able to access and/or change that variable across all swift files. For example, I have a view controller file for the user's profile page and a settings page - I want to be able to access and change that variable in either of those files. I have tried making a class file, but whenever I make an instance of that class in my view controller, I am able to access the default value of the variable in that class, but I am not able to permanently change its value.
So essentially, I want to be able to declare a global variable that is accessible by all files in my project, and can be changed by all files in my project.
Nevermind, I decided to use user defaults to save my variables, and I can then retrieve them from any file within the project.
For example:
//Declare this inside your class
let defaults = UserDefaults.standard
//Take any variable like this
var name: String = "Bill"
//and save them to UserDefaults
defaults.set(name, forKey: "name")
You can then access the variable in another class(or in the same class, just drop the "let" before "name") by calling:
if let username = defaults.string(forKey: "name"){
let name = username
The variable is accessible by the unique key you give it when calling the defaults.set() function. You can change the value the same way you initially declared it.

CDI - ContextNotActiveException - WebBeans context with scope type annotation #RequestScoped does not exist within current thread

Environment : WAS 8.0.0.10
CDI : 1.0 (Implementation OpenWebBeans)
Use Case: Server is executing the Java class asynchronously via TimerManager. I am trying to inject the cdi bean with Request scope into the class but when any method is called on the injection, below is the stack trace i am getting. If i use the Applicationscope instead of RequestScope in the injection, Code works fine.
Upon investigating the issue, i found that Request and Session context will not be active for the threads initiallized asynchronously by the container. Is there some way i can initialize the request and session context?
Error :
javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation #RequestScoped does not exist within current thread**
at org.apache.webbeans.container.BeanManagerImpl.getContext(BeanManagerImpl.java:358)
at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:124)
at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.invoke(NormalScopedBeanInterceptorHandler.java:95)
at com.ford.it.processcontrol.TestJob3_$$_javassist_22.executeJobCB(TestJob3_$$_javassist_22.java)
I'm assuming you already have this, or something alike somewhere:
CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();
cdiContainer.boot();
ContextControl contextControl = cdiContainer.getContextControl();
Then, somehow you have access to the ContextControl instance. Then you can start the context wherever you need it, just remember to stop it when it's no longer needed
try{
//start
contextControl.startContext(RequestScoped.class);
// do stuff
}catch(Exception e){}
finally{
//stop
contextControl.stopContext(RequestScoped.class);
}
This is working for me in some asynced classes.
Hope it helps.
regards!

SSJS global variable seems not working

I had declared and used a global variable in ssjs library as below:
var backendDoc:NotesDocument = null;
function savedata () {
print (backendDoc.getItemValueString("fieldname")); // crash here
}
I assigned a document object to it in the Edit button just after changing docuemnt mode from read to edit:
backendDoc = document1.getDocument(); // get backend document from datasource called document1
The code in above function return error NotesDocument.getItemValueString("string")) null. Apparently, the backendDoc is null.
Any ideas how to assign value and use global variable in ssjs library? Thanks in advance
There are 2 problems with your code:
as Michael pointed out: you should use a scoped variable. Global variables in script libraries are actually application global (think applicationScope) and might be unloaded any time if memory gets tight (behavior of them depends on the XPages version)
You can't use NotesObjects here. Between the calls the C Object that backs the JS object is released and your object becomes invalid.
You can either store the NoteId in a scoped variable and retrieve the NotesDocument every time or actually use a JSON structure to keep the values you are interested in and only read/write when actually needed (load/save event). Hope this helps
I think you have to use a scoped variable in which you store the universalid of the document. This can then be used at any script to initialize the backend document.
From a ssjs you can set a scoped variable using the put method and the get method to read the variable. Example to set and read a scoped variable in session scope :
sessionScope.put(“myvar“,“myvalue“)
sessionScope.get(“myvar“)
To learn more about scoped variables watch this
http://notesin9.com/index.php/2009/11/07/episode-4-intro-to-scoped-variables/

How can I add a JSON object to a scoped variable in Java?

I have used many JSON object in applicationScope, sessionScope, and viewScope to track related data. Writing and reading these in SSJS is very simple:`
//Create a app scope variable
applicationScope.put("myvarname", {p1:"part 1", p2:"part2"});
// read and use the app scope variable ...
var myvar = applicationScope.get("myvarname");
//Work with parts as myvar.p1, myvar.p2, etc...
In the Java code I have been writing I have learned to read these variables which were written using SSJS using the com.ibm.jscript.std.ObjectObject package with code like this:
ObjectObject myvar = (ObjectObject) ExtLibUtil
.getApplicationScope().get(dbkey);
FBSValue localFBS = myvar.get("p1");
String myp1 = localFBS.stringValue();
localFBS = myvar.get("p2");
String myp2 = localFBS.stringValue();
Now, of course, I want to write a new entry using the Java Bean that can then be read by SSJS and other Java Beans in the same manner. I managed to write to the scope using a Map and a Hashtable, but these crash the logic when trying to read using the ObjectObject.
So, how would I go about building a new entry in the scope using the ObjectObject and/or FBSValue packages? I cannot find how to create a new FBSValue that can then be added to an ObjectObject. I am sure it is a simple thing a Newbs like me has missed.
/Newbs
You can construct an empty ObjectObject, populate it with FBSValues, and just put it directly into the scope Map:
ObjectObject myvar = new ObjectObject();
try {
myvar.put("p1", FBSUtility.wrap("part 1"));
myvar.put("p2", FBSUtility.wrap("part 2"));
} catch (InterpretException e) {
e.printStackTrace();
}
Map<String, Object> applicationScope = ExtLibUtil.getApplicationScope();
applicationScope.put("myvarname", myvar);
When retrieving it later (as in the examples you provided), SSJS will see it as JSON, Java will see it exactly as it was stored.
If you need to store deeper hierarchies, you can put instances of ArrayObject and ObjectObject inside an ObjectObject in addition to primitives, so, just like JSON itself, you can nest these as deep as you need.
Just be sure to only include true JSON (strings, numbers, booleans, arrays, objects) if you'll be storing it anywhere higher than the requestScope; specifically, FunctionObject does not implement Serializable, so JSON is safe to store, JavaScript is not. Strictly speaking, this only becomes toxic when stored in the viewScope in 8.5.2 and 8.5.3 (and even then, only when the application's persistence option is not set to keep all pages in memory). But if IBM ever implements cluster support, then all objects stored in sessionScope and applicationScope will need to be serializable to allow for inter-server state transport... so, in the interest of future-proofing the design, it's wise to hold to this principle for anything stored longer than the duration of a single request.

JSFUnit accessing FacesContext before JSFSession is created

I want to access the JSFUnit FacesContext before I create the JSFSession object. The reason for this is I would like to set a managed bean value before any request/response processing is done. I use this value in a filter.
I am not sure exactly what do you want to accomplish, however, if you want to set values before any request will be processed, use WebClientSpec with setInitialRequestStrategy.
For example, you can use FormAuthenticationStrategy:
WebClientSpec wcSpec = new WebClientSpec("/secure.jsp");
FormAuthenticationStrategy formStrategy = new FormAuthenticationStrategy("user", "password");
formStrategy.setSubmitComponent("login_button");
wcSpec.setInitialRequestStrategy(formStrategy);
JSFSession jsfSession = new JSFSession(wcSpec);
or define your own custom request strategy that implements InitialRequestStrategy.
See FormAuthenticationStrategy code and create something similar to it.

Resources