Where should I put Scope variables in XPages - xpages

I have an XPages Library database where all my XPages are created. From there users will access other databases to do their work.
I need to put the names of those databases in variables so they can be found on any server (development, test, production, etc.) since the names are always the same. I think that those variables should be applicationScope variables but I am not sure.
If applicationScope in the variable that I need, can you tell me where is the best place to create them.
If it is not the right variable, which kind of variable will be the best and where do I define them.

An easy way to deploy some static references is the xsp.properties file. This file allows to add variables which are accessable on all XPages applications on the server
For example this variable...
myproperty.test=Hello World
... can be accessed in any XPage this way:
context.getProperty("myproperty.test")
These properties can be set by a theme too.
But the property has to be added to any server manually.
Another way is to use configuration documents: These can easily deployed by the replication mechanism to any database on any server. The value of these documents can be cached in applicationScope variables for a better performance.
EDIT:
You should alter the XSP.properties file on the server, not the database specific One. This does not require a Designer, only a text Editor is required.

applicationScope variables stay in memory about 10-15 minutes and are discarded after that. If I understood your need correctly, you should store the database names or URLs permanently and Notes documents would be the best fit for that.

The disadvantage of putting the values into a.properties file is that you need a designer Client to make changes.
I would suggest to use a global configuration document for your application that can be edited either in the client or using an XPage.
Take a look into the xhelp application by Paul Withers. Dig into the code to see how you can use a configuration document in your application. XHelp can be donloaded from here http://www.openntf.org/internal/home.nsf/project.xsp?action=openDocument&documentId=426CB81230B6F94A8625789000830762

I think because you are talking about a portal like application that it would be best to have a settings document implementation. You have to create an admin xpage which will check if there will be a document of a certain type in the lookupsettingsview ( you have to create this yourself ofcourse ). If there is none create the document. If there is one use the document as the datasource.
On this document you can store the replication id's and server information about the applications you want to display. This can be a simple form with a multiline text field on it. The data could be stored in a format like "Description$repid$server". On the web you have to check for this document, read the entries in the document using a repeat. For each iteration you can just use a xp:link tag. Ofcourse you first need to compute the url of the applications but that's not the biggest issue here.

Related

Is there a way to restrict CRUD operations on Notes/Domino data using an alternative application?

We have a (super)user who has been using VBA in an Excel spreadsheet to create and manipulate documents in a Domino database application.
The user has 'Editor' access to the application, and should normally be able to create/edit the document contents.
They have been, however, creating documents using VBA. That logic doesn't consider such important document fields as Readers, Authors, etc. .
We would like to restrict access to all Domino data so that it can only be created/modified using an IBM Notes client.
I have tried looking through the ECL, but that only restricts what 'others' do.
Since he has his Notes client available, the external logic is using his normal Notes credentials.
I have tried setting a hidden field with the Notes client and looking for that in the QuerySave event of the form design.
Unfortunately, the external code pays no attention to the form events and the save is executed despite the missing field.
Similarly, the Database Script has no bearing on the execution of external logic.
I was going to inspect the client version upon database open and restrict activity based on a variance in the version (I was hoping!).
I have de-selected the 'Don't prompt for a password...' option in the user security preferences, but that has no effect at all (suspected as much!).
The ONLY thing I have been able to suggest is to hide the database design... That's really only designed to thwart a user's efforts to understand the underlying design.
It won't prevent them from creating hundreds of thousands of documents with a fictitious form and throwing the app into disarray.
I'm hoping that there is a solution out there that I'm missing.
The user has been instructed not to undertake such activity in the future.
We were lucky that there really wasn't any malicious intent - "Just trying to be more efficient" we're told.
The effects of the activity have been remedied, and the user has been warned.
What I want to know is... how can I prevent this from ever happening again?
The circumstances are rare I know, but I would've thought there'd be a means of restricting the platforms used to manage Notes/Domino data.
Is there a way to ensure no external applications are able to access, create or modify Notes database documents?
I am currently focussing on access to Notes via COM.
I thought that, if I unregistered 'nlsxbe.dll' from the registry, that would prevent such activity - It has not.
I also tried removing the .TLB files from the Notes executable folder - removal of 'notes32.tlb' and 'domobj.tlb' have no effect at all. Removal of 'ltsci3.tlb' screws everything up (as expected!).
I'm really having no luck at all - Any/all suggestions would be most appreciated!
I'm not aware of any way to detect that a connection has been made by standalone code instead of by the Notes client, but you do have two paths available to you:
A Domino server add-in that prevents documents from being saved in that particular database if certain criteria aren't met.
An agent that is triggered to run shortly after documents are saved or modified in that particular database. The agent code can delete (or modify, if you prefer) the documents that don't conform to the required criteria.
The server add-in route would normally require coding in C, but thanks to the Open NTF Trigger Happy project, the hard part is done for you, and the rest can be filled in with either LotusScript or Java agent code that is "triggered" by the pre-written C code. You will need to have some basic knowledge of how the Notes Extension Manager interface works, but once you get past that and write your agent code to enforce your data consistency/integrity requirements, the only real hurdle is your willingness to host open source code on your server.
There may be two other possibilities, but I can't say if either will solve or deal with the issue...
In the ECL you can disable 'COM' access for the user (also known as OLE or ActiveX) automation since VBA access is usually via COM. This has stopped Notes using external COM access for me, but I don't know if also prevents VBA using Notes. Additional steps may be needed to enforce the ECL and apply to the specific users.
There is an (old) notes.ini 'DisableExternalApps' (or something similar) that disables some external access. This can affect many things (DDE/Prompts/#dblookups) but again I don't know if this will disable VBA/COM and its not user specific, but server wide.
I would have thought that removing the nlsxbe.dll or restricting access to execute it might work, but the ECL may be the best bet.
Alternatively, rather than add hidden flags to your design (and the documents), and then delete the offending documents, your agent could apply the correct author/reader fields to the documents instead.
Very tricky. Did you find a better solution?

Web Part Storing Persistent Variable (ViewState/Session?)

I am developing a custom SharePoint 2010 Web Part (not visual) in C#.
I need the ability to maintain persistent variables (selected value of a drop down list for example) across postbacks but have it be unique to each individual User and page/tab that the web part is in. Storing the variable in Page.Session accomplishes the per user requirement but persists the variables value across the same windows/tabs for that user. This link describes what I have done, but it definitely not unique per window/tab.
I am not sure of the best way to store the variable, but I have attempted to use ViewState unsuccessfully. I have confirmed in the web.config that it is enabled, but am unable to use ViewState in the same way I use Page.Session Can anyone please help?
Perhaps Postback was not the correct term? My code is actually: Context.Response.Redirect(Context.Request.RawUrl);
Thanks,
MK
Is there a reason you are using "Context.Response.Redirect(Context.Request.RawUrl)"?
You are wiping out View-State data loading the page this way.

Persist Local Configuration Data in SharePoint

I have a piece of data, a simple string containing the server name that the SharePoint solution is deployed to, that I retrieve from a configuration store in a helper method in a common DLL used throughout my solution. This helper method is used throughout my custom pages and web parts, to build a number of URLs, etc.
I would like to persist this string, and prevent it being repeatedly retrieved from the configuration store. My Sharepoint installation is currently on a single server, but will be migrated to a SharePoint server farm in the near future, so simply determining the server name of the current request, etc isn't an option. I have looked at caching as described in the best practices for SharePoint, but unless I use a coherent cache like NCache or Velocity/AppFrabric, I will again have issues when the move to server farm occurs. Given that this is a single string, adding a full caching solution such as Velocity seems like overkill.
Does anyone have any suggestions on the best way to persist this data? Am I missing something obvious here?
Thanks, MagicAndi
Look into using the Property bag that is exposed by all major SharePoint objects to persist information. i.e.
SPFarm.Properties
SPWebApplication.Properties
SPSite.Properties
You could:
Store the string in web.config. You can programatically change the web.config on all the farm's webservers using a SPWebConfigModification
Store the string in a SharePoint list and read from it. I usually use this solution because I have more to store than a single string. The list is 'available' on all web servers and I cache its values in an ASP.NET cache object. Someone made this concept into a solution you can download and install: SPConfigStore
This article may be of use to those looking at storing configuration data in SharePoint:
Six ways to store settings in SharePoint
You can use SPPersisted to do such kind of operations.

How can I programmatically determine the creator of a Domino database?

I'm using the built-in Domain Catalog database to list all the databases on a particular Domino server. I'm creating a custom view to show certain information about each database. What I'd like to have is a column that displays the creator of each database. However, if the Domain Catalog is keeping track of this information, I can't find it.
Is there a field in the Domain Catalog that provides this information that I just haven't been able to find? Is there some other way I might find this information and get it into this view? #DBlookup and related functions don't work in column formulas.
That information is not stored in the catalog, and is probably not stored in the database either (It's not shown on any of the property tabs).
You would probably need to get/write a server add-in to monitor database creation and store that data somewhere. Then you'd need to account for databases created by adminp/replication - your add-in might pick them up as having been created by a server.
This question was also asked in the R4/R5 forums in 1998 and received no answer.
Interesting question. There is no such attribute for database, but you can dig for some clues.
New databases: use NotesNoteCollection and look for some specific design element (icon, for example) and look for first element in $UpdatedBy field.
New copies/from templates: above mentioned method won't work. It will return info from original/template, not current database. In this case, try using Created property of DB and check user footprints after that date - in ACL log (he probably altered ACL immediately after copy), new design elements (probably made new view, folder, agent...) or profile documents.
What Frantisek said. Looking in the log archive (ugh!) may tell you who deployed it, but in a well run environment that won't be who developed it. A list of $UpdatedBy(0) for all design notes should give you a good idea. The catch will be that it mayl be people who left the company years ago. : )

SharePoint - Connection String dialog box during FeatureActivated event

Does anyone know if it is possible to display a prompt to a user/administrator when activating or installing a sharepoint feature?
I am writing a custom webpart and it is connecting to a separate database, I would like to allow the administrator to select or type in a connection string when installing the .wsp file or activating the feature.
I am looking inside the FeatureActivated event and thinking of using the SPWebConfigModification class to actually write the connection string to the web.config files in the farm.
I do not want to hand edit the web.configs or hard code the string into the DLL.
If you have other methods for handling connection strings inside sharepoint I would be interested in them as well.
Unfortunately there is no way to swap to a screen where you can get user via the feature activation process. Couple of comments for you:
I'm assuming the connection string is going to be different for every installation, so there is no way you can include it directly in the Solution.
I'm assuming that you couldn't programmatically construct this during installation.
Therefore, you need some way to get user input. Here are a couple of options:
It could be a web part property, though this would mean setting it each and every time the web part was added, and you would need to then maitain those settings individually.
You could build out your own _layouts settings screen (good post: http://community.zevenseas.com/Blogs/Robin/archive/2008/03/17/lcm-creating-custom-application-page-and-using-the-propertybag-more-detailed.aspx), and from there users can maintain the property, storing it in either the Web Property bag, or inside the Web.Config. I try to avoid using the Web.Config where I can, but if you do wish to go this route then MAKE SURE you use the SPWebConfigModification class (Read this great blog: http://www.crsw.com/mark/Lists/Posts/Post.aspx?ID=32)
Finally, a technique I often use is storing configuration information in a SharePoint List. Chris O'Brien has a great framework for that here: http://www.codeplex.com/SPConfigStore
Hope that helps,
Daniel
Sounds good. I will look at these possible solutions.
I do not think #1 will work since I am deploying multiple webparts inside a single solution which all use the same connectionString.
#3 sounds like a very clean solution. I see the config items are cached so it looks like if I need to store a connection string, I will not be hit with a SP lookup each time I need that string.
While searching for a solution I did stumble across another method.
If you dig around their code, I looks like they have created an installer that accepts application specific values, adds the values into a FeatureTemplate.xml file and passes them to the SPFeatureReceiverProperties object in the Reciever.
I was about to start tackling this method, but I think #3 would be better.
Thank you,
Keith

Resources