On stackoverflow.com, an interessting topic was asked about how to create a notes database programmatically without using a template. The problem is, that it will not contain a Icon document. But in this document are all database properties stored. So the question is: How can you create this document?
Jesse Gallagher came up with the idea to use the DXL import and create the Icon document this way, which works fine. But the next problem is, that there is no ACL note in the database and no default view.
That’s why I modified his idea and created a Java Utility class. This class creates a new database which includes all of the required design elements.
package ch.hasselba.core;
import lotus.domino.ACL;
import lotus.domino.Base;
import lotus.domino.Database;
import lotus.domino.DbDirectory;
import lotus.domino.DxlImporter;
import lotus.domino.Session;
/**
* DB Utilities
*
* @author Sven Hasselbach
* @version 1.1
*/
public class DBUtil {
/**
* creates a new database
* the database is identically to a database created by the -blank- template in designer.
* The default access is set to Manager
*
* @param session
* the session used to create the database
* @param dbTitle
* the database title
* @param dbPath
* the path of the database
* @param dbServer
* the server
*
* @version 1.1
*/
public static void createDatabase( Session session, final String dbTitle, final String dbPath, final String dbServer ) {
DbDirectory dbDir = null;
Database db = null;
DxlImporter importer = null;
ACL acl = null;
try{
// create a new database
dbDir = session.getDbDirectory( dbServer );
db = dbDir.createDatabase( dbPath );
// initialize dxl importer
importer = session.createDxlImporter();
importer.setDesignImportOption( DxlImporter.DXLIMPORTOPTION_REPLACE_ELSE_CREATE );
// generate DXL
String dxl = generateDXL( dbTitle, dbPath, db.getReplicaID() );
// import DXL
importer.importDxl(dxl, db);
// set ACL: Default to Manager
acl = db.getACL();
acl.getFirstEntry().setLevel(ACL.LEVEL_MANAGER);
acl.save();
}catch(Exception e){
e.printStackTrace();
}finally{
recycleObj( acl );
recycleObj( importer );
recycleObj( db );
recycleObj( dbDir );
}
}
/**
* generates the DXL for a blank database
*
* @param dbTitle
* the title of the database
* @param dbPath
* the path of the database
* @param dbReplicaId
* the replica of the database
* @return String with DXL
*
* @version 1.1
*
*/
private static String generateDXL( final String dbTitle, final String dbPath , final String dbReplicaId ){
StringBuilder str = new StringBuilder();
str.append("<?xml version='1.0' encoding='utf-8'?>");
str.append("<!DOCTYPE database SYSTEM 'xmlschemas/domino_8_5_3.dtd'>");
str.append("<database xmlns='http://www.lotus.com/dxl' version='8.5' maintenanceversion='3.0' ");
str.append("replicaid='");
str.append( dbReplicaId );
str.append("' path='");
str.append( dbPath );
str.append("' title='");
str.append( dbTitle );
str.append("' allowstoredforms='false' ");
str.append("usejavascriptinpages='false' increasemaxfields='true' showinopendialog='false'>");
str.append("<databaseinfo dbid='");
str.append( dbReplicaId );
str.append( "' odsversion='51' ");
str.append("numberofdocuments='0'></databaseinfo>");
str.append("<note default='true' class='icon'>");
str.append("<noteinfo noteid='11e'>");
str.append("</noteinfo>");
str.append("<item name='IconBitmap' summary='true'>");
str.append("<rawitemdata type='6'>");
str.append("AiAgAQAA///////wD///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfgAAAHwAAAA8AAAAPAAAADgAAA");
str.append("AYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAHAAAADwAAAA8AAAAPgAAAH4AAAB/AAAA/4AAAf");
str.append("/AAAP/4AAH//gAH///AP//////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAiIiIiAAAAAAAAAAAAAAI");
str.append("jPZmZm/IgAAAAAAAAAAIjGZmZmZmZsiAAAAAAAAAjGZmZmZmZmZmyAAAAAAACMZmZmZmZmZmZmyA");
str.append("AAAAAIxmZmZmZmZmZmZmyAAAAAjGZmZmZmZmZmZmZmyAAAAIZmbyL2byL2byL2ZmgAAAjGZmIiJm");
str.append("IiJmIiJmZsgAAIZmZiIiZiIiZiIiZmZoAADGZmYiImYiImYiImZmbAAI9mZmIiJmIiJmIiJmZm+A");
str.append("CGZmZiIiZiIiZiIiZmZmgAhmZmYiImYiImYiImZmZoAIZmZmIiJmIiJmIiJmZmaACGZvIiIiZiIi");
str.append("ZiIiIvZmgAhmYiIiImYiImYiIiImZoAIZm8iIi9m8i9m8iIi9maACPZmZmZmZmZmZmZmZmZvgADG");
str.append("ZmbyL2byL2byL2ZmbAAAj2ZmIiJmIiJmIiJmZvgAAIxmZiIiZiIiZiIiZmbIAAAI9mbyL2byL2by");
str.append("L2ZvgAAACMZmZmZmZmZmZmZmbIAAAACMZmZmZmZmZmZmZsgAAAAACMZmZmZmZmZmZmyAAAAAAACM");
str.append("9mZmZmZmZm/IAAAAAAAACIz2ZmZmZm/IgAAAAAAAAAAIiMZmZmyIgAAAAAAAAAAAAACIiIiIAAAA");
str.append("AAAAUEECICABAAD/////+A4DgA==");
str.append("</rawitemdata></item>");
str.append("<item name='$Daos'><text>0</text></item>");
str.append("<item name='$TITLE'><text>");
str.append( dbTitle );
str.append("</text></item>");
str.append("<item name='$Flags'><text>7f</text></item>");
str.append("<item name='$FlagsNoRefresh'><text/></item></note>");
str.append("<view xmlns='http://www.lotus.com/dxl' version='8.5' maintenanceversion='3.0' ");
str.append("replicaid='");
str.append( dbReplicaId );
str.append("' showinmenu='true' publicaccess='false' default='true' noviewformat='true'>");
str.append("<noteinfo noteid='11a' sequence='1'></noteinfo>");
str.append("<code event='selection'><formula>SELECT @All</formula></code>");
str.append("<item name='$FormulaClass'><text>1</text></item></view>");
str.append("</database>");
return str.toString();
}
/**
* recycles notes objects
*
* @param obj
* the notes object to recycle
*/
private static void recycleObj( Base obj ){
try{
if( obj != null )
obj.recycle();
}catch( Exception e ){}
}
}
Here is an example XPage how to use the class:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
DB Path:<xp:inputText id="inputTextDBPath" value="#{viewScope.dbPath}" /><xp:br />
DB Title:<xp:inputText id="inputText1" value="#{viewScope.dbTitle}" /><xp:br />
<xp:button value="Create DB" id="buttonCreateDB">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<![CDATA[#{javascript:
importPackage( ch.hasselba.core );
var dbUtil = new ch.hasselba.core.DBUtil();
dbUtil.createDatabase(session, viewScope.dbTitle, viewScope.dbPath, "");
}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:view>
You can enter the database Title and the database path. After clicking the button „Create DB“, the database is created on the server (assuming you have the right to do that).
I was looking into this last week for XPages. you timing is impeccable. Thanks
I like this for a quick bootstrapping of an empty database. I’ll likely adopt the idea for an „initialize“ method in the design portion of the OpenNTF API to populate a fresh NSF with some sensible defaults.