how can I access endpoint properties set in faces-config.xml programmatically? - xpages

I am using the IBM Social Business Toolkit. I have defined a connection for my Notes app via endpoints in the faces-config xml file. I wonder how I can access this file pro grammatically since I could not find a service that returns me the base url of IBM Connections.

It's useful to remember that an endpoint definition is really just creating a managed bean. The managed bean has a variable name you refer to it - the managed-bean-name property. You can access this directly from SSJS or via ExtLibUtil.resolveVariable() in Java. The definition also tells you the Java class that's being used, e.g. com.ibm.sbt.services.endpoints.ConnectionsBasicEndpoint. That really gives you all the information you need to get or set the properties.
So from SSJS you can just cast it to the class name, e.g.
var myService:com.ibm.sbt.services.endpoints.ConnectionsBasicEndpoint = connections
So the bit after the colon will be the managed-bean-class value and the bit after the equals sign will be the managed-bean-name. In Java, you can use
ConnectionsBasicEndpoint myService = (ConnectionsBasicEndpoint) ExtLibUtil.resolveVariable(ExtLibUtil.getXspContext().getFacesContext(), "connections");
You'll then have access to all the methods of the class, so you should be able to retrieve what you need.

The properties are part of the Java class, who are referred to in the Faces-Config.xml. So get the class by his fully qualified name or by bean name and set or get the properties

I think the best route will most likely be what Paul is suggesting: resolve the variable by its name and use the getters to get the effective properties that way.
Sven's suggestion is a good one to keep in mind for other situations. By accessing the faces-config.xml file as a resource, you could load it into an XML parser and find the values using XPath. I'm doing much that sort of technique in the next version of the OpenNTF Domino API, which will have a set of methods for manipulating the Faces config. However, one key aspect there is that reading the XML file directly will just get you the string values, which may be EL expressions, whereas going the resolveVariable route will get you the real current properties.

Related

What is the "binding" property of controls and how do you use it?

The "binding" basic property is described as a property that "Specifies an expression that binds a control to a particular control property". I tried to google and read at HCL docs but there is no example on how to use it.
The binding property allows you to specify an object property (say, on a managed bean or dataContext) that will be set to the specified component. For example, you could do:
<xp:inputText binding="#{someBean.textField}"/>
...and that would call someBean.setTextField(XspInputText inputText).
All that said, it's kind of an edge-case property. I've made good use of it, but it's largely an artifact of earlier JSF revisions, when it was more common to have backing logic that "knew" about the front-end XPage explicitly.
In general, it's better design to stick to value bindings like value="#{someBean.firstName}" and not make your backing objects aware of the front-end UI, unless you have an explicit reason to do otherwise.

User roles and workflow status xpages and managed bean

To not have to keep repeating some validations, for example, who can see a button in a certain status of a document in the worlflow, I'm using session, scope, and session variables to store the user roles and application variable to store the Status related to each area.
I was evaluating whether it would be better from a performance and build point of view to implement a managed bean, to return the user roles and the possible statuses of each participating workflow area. Would it be the best structure in fact? What do you think? I do not have much experience in java. How could I construct the structure in java, several methods, one for roles and the other for set of status associated with the area that would name the related method? You could return the results of this method in arrays, or there is a better return structure.
Thanks a lot!
My best suggestion is to adopt the pageController Methodology. Then it's more like true MVC. This has been talked about on NotesIn9 screencast many times but basically you have a java object that's bound to your XPage. In effect it's a viewScoped bean that holds all your page logic. Then you can have methods like isGroupMember(), hasRole() etc and calculate that on the pageInit. There's little need to hold onto that in sessionScope in my opinion. So for example I have this in my pageController :
public boolean isGroupMember(String groupName) {
return JSFUtil.getXSPContext().getUser().getGroups().contains(groupName);
}
So that's available to each page. BUT I don't need to copy that snippet onto every page controller. In Java you can have your page controllers extend a more generic class. so I have a "base.pageController" class. All the specific page controllers extend that. So this isGroupMember() code goes into the base and then it's available to be used on every XPage. Doing it this way gives you the ability to have generic functions like this and then hold more specific function that are only for the individual page.
You can also have a hasRole() function etc...
Recommend you check out this video : http://www.notesin9.com/2016/08/25/notesin9-196-no-dependency-page-controllers/
Also for a question like this, I recommend you just use the xpages tag. Adding others like javabeans can bring people in who know nothing about XPages and XPages is unique enough of a beast that outsiders can cause some confusion on occasion.

Storing properties of a custom component in session scope or bean

I've written a new back-end Java component (extending UIComponentBase) as an alternative for the ExtLib Application Layout control. The control needs to show a collection of data that is looked up from another Notes application. The data is user dependant and doesn't change from page to page so, to avoid repeatedly doing a lookup to the other application, I want to store it in the session scope. (Note that because this is a layout control, there will only ever be one per page.)
I know I could use a session-scoped maanged bean (and have done in previous iterations) but the data only needs to be used in this control and shouldn't be used elsewhere on the page which it could be with a bean. So my question is, what's the best practice approach I should take here? Should I just directly store the data in the sessionMap or am I missing a trick with the component stateHolder? Or am I stuck with using a bean?
Thanks
(Edited for clarification)
It looks like you're talking about your own back-end Java components rather than Custom Controls within a single NSF.
I'm not sure at what level, when you write your own native XPages components, the properties are cached by the stateHolder when calling saveState(). I would presume no higher than View, for the reasons Frantisek says, that otherwise it would be unclear which instance to update if you had multiple on one XPage but one on another. It couldn't update both at the same time on the same page, so I would guess that each is a separate instance. As a result, the same component on multiple pages would be a separate discreet instance.
But there's nothing stopping you, in specific setters of the component, writing to sessionScope as well as the private property, and then doing the reverse on the getter. I'm not sure if you'd want to try the internal property before trying sessionScope or vice versa. It would depend how you wanted to handle the situation of the same sessionScope being updated from multiple pages (if the collection could change).

Customize DataService namespace and EntityContainer

Nutshell: The Entity Framework Provider for WCF Data Services pulls the schema namespace and EntityContainer name directly from the namespace and class name of the DbContext, respectively. This is also true for DbContexts that are developed using the code-first method.
Is there a way to modify this provider behavior a posteriori--that is, without modifying the class name or the EDM(X)?
Background/caveats/opinion: This is a handy behavior for prototyping, but in a production scenario, the class name is itself an implementation detail that should be hidden from service consumers.
Further, in my case the name cannot be changed, since I am using a framework that provides a very generic DbContext that I am then composing/extending.
Note that I am not discussing a way to create more "space" between the CLR and EDM representations of the data model. Rather, I'm looking for a way to modify the behavior of the DataService<T> extension itself, so that the internal CLR namespace and DbContext extension class name (preserved in the EDM, which is totally okay) aren't exposed externally.
The specific customization points in the service metadata (custom-ns and custom-container below):
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:DataServices m:DataServiceVersion="1.0" m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<Schema Namespace="<custom-ns>" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityType Name="EgEntity">
.
.
.
</EntityType>
.
.
.
<EntityContainer Name="<custom-container>" m:IsDefaultEntityContainer="true">
<EntitySet Name="EgEntity" EntityType="<custom-ns>.EgEntity" />
.
.
.
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
In code-first, you can specify the schema for tables in the SSDL with the Table annotation (look at the Schema property). Unfortunately, I don't think you can overwrite the schema namespaces used in the CSDL with either attributes or the model builder (please note that I haven't extensively researched this).
You may attempt to play with namespace aliases, although I'm not sure this would work as you intend.
In model-first and database-first, see this question which seems to answer yours. Let me know if it doesn't.
I realize this answer is not too helpful, but I would like to suggest that you specify proper namespaces for your codebase, even (especially) for production. This is because I can't immediately see why a namespace should be "hidden" in any normal scenario, but please do expand on your use-case if you disagree.
That being said, I agree that one should be able to map proper CLR namespaces to different EDM schemas for other reasons, I guess everybody is OK with using the same names as long as they make sense. By the way, don't forget vendor prefixes, especially since you're exposing these names to the network.
Note that the third-party framework namespace shouldn't be relevant as long as the context class is not sealed. Usually, entities are defined as POCOs so that's normally not a problem either. Thus, the standard solution would be to extend this generic context class in a namespace of your own, along with the entities.

Persisting ViewScoped beans across multiple views

Ok I know scope questions come up all the time but I'm interested in a slightly different approach to the solution. The #ViewScope is a fantastic bridge between the #RequestScope and the #SessionScope.
However there is still a common use case (at least for me) where I really don't want to use #SessionScope but I need the data over a couple of views. A really simple case is when I have multiple datatables chained together each one depending on previous selections.
It's perfectly possible to use <f:paramView> and pass a single or even a couple of pieces of data as params in the address and then retrieve everything from the database again. I am more interested in finding a way of creating a 'snapshot' of the beans state / variables, creating the new #ViewScope and then 'restoring' the 'snapshot state' to the new bean.
Does such a thing exist? Ideas? Opinions?
I don't know if this is the 'accepted solution' but I've implemented an idea that works for me. (Feedback appreciated!)
So I have created a #SessionScoped class with a couple of static maps:
private static Map<String, Object> objectVariableMap;
// Getters, setters and methods etc. are omitted for simplicity
The idea being that I have specified a map that accepts a String as the key and an Object as the value. I've specifically not set the type of object to allow me to store any type of object in there. The caveat is that you need to be sure of the type of object when retrieving it so you can cast it back into its original type.
Now comes the time to set the data from the first #ViewScoped. I generate a random UUID (or what ever you want) as the Map key and then set the value to the object I'm working with (ie. this, or indeed any other objects you might want to pass to the next view). Save the key, value into the map and set the URL param to the key.
I'm never keen on passing data like user id's etc. in URL params (even when its encrypted). This idea has the added benefit of offering disposable URL values that have a specifiable life span.
On the receiving end (ie. The new #ViewScoped bean, or any other scope for that matter) you read in the URL param (the map key) using <f:paramView> and then use a preRenderView event to retrieve and set the Object where working with.
At this point you can choose to remove the key pair from the Map and invalidate the ability to retrieve that object or you can keep keep the key pair for a longer duration by simply updating the object if there are any changes.
UPDATE: Conceptually this has been really successful (for me at least). I've created a handfull of useful methods and classes surrounding the concept to make it more universal. If anybody wants more specific instructions or I might even create a small library if anybody wants.
You can use the CDI "Conversation Scope" for this. This is narrower than the session scope but wider than the view scope.
If the pages between which you pass parameters are a unit, you can also make them a flow in JSF 2.2 and use the flow scope.
Projects like CODI offer various other scopes that can be used between pages.

Resources