bookmark_borderQUINDIP: set JAVA Compiler target in notes.ini

Literally EVERY time I created a Java agent or library the compiler target was set to 1.2 even though I have been using LN 7 or later…
I always had to find the noteId and use a tool to manually change the source and target to 1.6.

here’s how you can change that behaviour:
http://www-10.lotus.com/ldd/ddwiki.nsf/dx/07152009034956PMMSTR75.htm

enjoy

AND make sure you add an EMPTY at the end in case JavaCompilerTarget=1.6 is your last line! otherwise this setting will not be used!

bookmark_borderINDIP: sort a document collection in Java (Java heroes may skip this)

Update: the result of the blog below landed here. Thanks to Nathan Freeman, hihi, kudos to me???

In Lotus Script it was not a simple task to sort a document collection. In Java it sort of is.

Idea: use a comparator class, supply with an array of fields upon which the “sorting” should happen and let the Collections.sort do it’s magic:

Comparator class:

public class CollectionComparator implements Comparator<Document> {

String[] sortFields = null;

public CollectionComparator(String[] sortFields) {
this.sortFields = sortFields;
}

public int compare(Document doc1, Document doc2) {

try {
int compared = 0;
// loop all sortFields
for (String field : sortFields) {
Item item1 = doc1.getFirstItem(field);
Item item2 = doc2.getFirstItem(field);
switch (item1.getType()) {
case Item.TEXT:
case Item.AUTHORS:
case Item.NAMES:
case Item.READERS:
String val1 = doc1.getItemValueString(field);
String val2 = doc2.getItemValueString(field);
compared = val1.compareTo(val2);
if (0 != compared) {
return compared;
}
break;
case Item.NUMBERS:
Double d1 = doc1.getItemValueDouble(field);
Double d2 = doc2.getItemValueDouble(field);
compared = d1.compareTo(d2);
if (0 != compared) {
return compared;
}
break;

case Item.DATETIMES:

DateTime dt1 = item1.getDateTimeValue();
DateTime dt2 = item2.getDateTimeValue();
compared = dt2.timeDifference(dt1);
if (0 != compared) {
return compared;
}
break;
}

item1.recycle();
}
return 0;
} catch (NotesException e) {
Logger.logError(e);
}

return 0;
}

}

Calling the sort:
// fill a list with the documents
List<Document> docs = new ArrayList<Document>();
doc = dc.getFirstDocument();
while (null != doc) {
docs.add(doc);
doc = dc.getNextDocument(doc);
}

// sort the list
String[] sortFields = new String[] { “fieldName” }; // you can also supply multiple fields “field1”, “field2”
Collections.sort(docs, new CollectionComparator(sortFields));

// retrieve values
for (Document docSorted : docs) {
values.addAll(docSorted.getItemValue(“Values”));
}
All code samples and downloads are copyright Michael Zischeck and licensed under Apache License 2.0 

bookmark_borderQUINDIP: dynamic “access controlled sections” ;-) in xPages

Some people faced the same problem than me: they wanted something like the “access controlled sections” in plain old LN development.
Mark Leusink
Russell Maher
Jeremy Hodge

None of the articles quite well didn’t explain how to set those ACLs dynamically..

I also tried to get set READER or EDITOR via something like:
return (condition to check) ? “READER” : “EDITOR”

but it wouldn’t work, especially not if in the condition the currentDocument was used. So what next?

I tried with a Bean, and it worked very smoothly. I put the code into the Bean constructor, the bean itself is a request scope bean, as (for whatever reason) I could not get view scope beans to work:

UIPanelEx panel = null;
ACL acl = new ACL();
ACLEntry aclEntry = new ACLEntry();
if (!(dominoDoc.getValue(“wfCurrentState”).equals(“1”) || dominoDoc.getValue(“wfCurrentState”).equals(“5”))) {
aclEntry.setRight(“READER”);
aclEntry.setType(“DEFAULT”);
aclEntry.setFullName(“*”);
acl.addEntry(aclEntry);

panel = (UIPanelEx) JSFConnector.findComponent(“panelRequestor”);
panel.setAcl(acl);
panel = (UIPanelEx) JSFConnector.findComponent(“panelDetails”);
panel.setAcl(acl);
panel = (UIPanelEx) JSFConnector.findComponent(“panelApprover”);
panel.setAcl(acl);
}


dominoDoc is the document source and the code prevents a few panels from being edited in all but in 2 workflow states (1, 5)

Neat!

bookmark_borderQUINDIP: format your custom type aheads properly

Did you read my blogs about cool type ahead features? really cool type-ahead and making type-ahead easy as pie.

Here’s the sequel on how to make the “custom” type-ahead also look really nice.

Java code to create custom type-ahead:

StringBuffer sb = new StringBuffer(“”);
StringBuffer sbNames = new StringBuffer(“”);
Session session = (Session)DominoUtils.getCurrentSession();
Database db = (Database) DominoUtils.getCurrentDatabase();
View view = db.getView(“lupCountriesByUNID”);

// apply the search, this can be anything, looking up by key and NOT forcing a match
// or an FT search, we use for different amount of characters different fields to search in
// 2 characters = ISO language code, 3 characters = ISO currency code etc.
view.FTSearch(“*” + searchValue + “*”, 0);

Document doc = view.getFirstDocument();
sb.append(“<UL>”);
boolean found = false;
while(null != doc ){
found = true;
sb.append(“<LI><TABLE class=”receivingCountry“><TR class=”level” + doc.getItemValueString(“Level”) + “”>”);
sb.append(“<TD class=”recCountryLevel“><span class=”informal”>Level: ” + doc.getItemValueString(“Level”) + “</span></TD>” );
sb.append(“<TD class=”recCountryName“>” + doc.getItemValueString(“R_CountryName”)+ “</TD>”);
sb.append(“<TD class=”recCountryDesc“><span class=”informal”>” + doc.getItemValueString(“R_CountryDesc”)+ “</span></TD>”); 
sb.append(“</TR></TABLE></LI>”);

doc = view.getNextDocument(doc);
}

if( !found){
sb.append(“<LI><span class=”informal”>no result</span></LI>” );
}
sb.append(“</UL>”);
return sb.toString();

CSS applied:

.receivingCountry{
table-layout: fixed; /* in my case important to make the sugguestions fit */
width: 380px; /* in my case important to make the sugguestions fit */
border-collapse: collapse; /* needed to make the space go away */
border: 1px solid #DDDDDD;
padding: 0;
margin: 0;
white-space: normal; /* in my case very important to make the table cells wrap */
}

.tundra .dijitMenuItem {
border: 0;
margin: 0;
padding: 0; /* needed to get rid of the space between items */
background-color: transparent; /* needed to get rid of the gray oneUITheme background */
}

.level1 {
background-color: #FFCC66;
}
.level2 {
background-color: #66CCFF;
}

.recCountryName{
vertical-align: top;
width: 200px;
}

.recCountryLevel{
vertical-align: top;
width: 80px;
}

.recCountryDesc{
vertical-align: top;
width: 200px;
}

Result:


bookmark_borderQUINDIP: how to set field values with java (or DominoDocument the magic animal)

Old approach:

   XspInputText field = (XspInputText) StandardUtil.findComponent(facesContext .getViewRoot(), “countryName”);

The annoying thing about this approach: You never know exactly which class the component has, ie. a “read only” field is not XspInputText etc., and thus you cannot just use this approach really transparently.

New approach:

DominoDocument dominoDoc = StandardUtil.getDominoDocument();
dominoDoc.replaceItemValue(“editableField”, new Date().toString());

It works for editable/hidden/disabled/readOnly fields!!!

And the best thing is: you do not even need to know the fields xPage name anymore! 

You only care about set in the binding property. This in effect speeds up development a lot, cause I do not need to check/modify field names in 2 places anymore.

addendum:
the getDominoDocument works like this:

DominoDocument dominoDoc = (DominoDocument) JSFConnector
.getVariableValue(“currentDocument”);
return dominoDoc;

and the JSFConnector you will find here (kudos to Karsten Lehmann)

bookmark_borderquindip: use ctrl F8 to switch perspectives

so you read my article about how easy it is to debug xPages and now get stuck in the debug perspective all the time but you would like to checkout your code etc?

simple: use <ctrl><F8> to switch perspectives.

If you open first all those perspectives you don’t need and close them via WindowClose Perspective then it’s a simple matter of <ctrl><F8> to switch between Debug and xPages perspective

ah.. as a side note:

did you know that you can actually “debug” the building of the xPage component tree itself?
Open the Package Explorer view and inside your LN application open the Localxsp folder. There you will find the Java classes which have been created out of the XML in the xPages designer!

You can then set a breakpoint in the Java class for your xPage here:

    protected AbstractCompiledPage createPage(int pageIndex) {
        return new nameOfYourXPage();
    }