defining an object property in a compositeData on a custom control - java

I'm building an application where I have mainDoc which can have one or more related notes Documents. In the mainDoc there is a repeat control that is bound to Payments.getAllItems(WFSMainDoc.getValue("LinkKey")); The java class Payments has methods that manipulate and ArrayList of PaymentItems. The getAllItems method grabs all of the related NotesDocuments and loads them into an ArrayList. If the ArrayList already exists it just returns the previously built ArrayList. The button in the Repeat sets viewScope.vsRIndex = rIndex; and viewScope.vsShowPayment = true; which now displays the panelPaymentDetail and the custom control that has a custom property of type java.lang.Object and load pItem using pItem = Payments.getItem(rIndex); return pItem;
all of the above works and I have a couple sample controls below. I have two issues:
1. The compositeData.pItem is computed over and over again and as far as I can tell keeps returning the original values from the Payments.getAllItems() even though I'm editing them in the payment input 'form' -- the question then is how can I block this repeated calculation?
The save button in the Payment Input custom control does not appear to fire (none of the print statements occur when clicked) I think the reloading of the Object pItem gets in the way.
Test Main Document Control:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:this.data>
<xp:dominoDocument var="WFSMainDoc" formName="frmMainDoc"
computeWithForm="onsave" ignoreRequestParams="false">
<xp:this.documentId><![CDATA[${javascript:var UNID:String = sessionScope.get("ssUNID");
(UNID == null || UNID == "") ? "" : UNID}]]></xp:this.documentId>
<xp:this.action><![CDATA[${javascript:if (sessionScope.containsKey("ssUNID")){
if(sessionScope.get('ssUNID').length){
sessionScope.get('ssAction') == 'edit' ? 'editDocument':'openDocument'
} else {
return 'createDocument'
break;
}
}else{
return "createDocument";
break;
}}]]></xp:this.action>
<xp:this.databaseName><![CDATA[${appProps[sessionScope.ssApplication].appFilePath}]]></xp:this.databaseName>
</xp:dominoDocument>
</xp:this.data>
Main document
<xp:br></xp:br>
<xp:inputText id="inputText1" value="#{WFSMainDoc.LinkKey}"
defaultValue="#{javascript:#Unique}">
</xp:inputText>
<xp:br></xp:br>
Other Fields and controls
<xp:br></xp:br>
<xp:panel id="panelPaymentContainer">
<xp:repeat id="repeatData" rows="10" var="pItem"
indexVar="rIndex">
<xp:this.value><![CDATA[#{javascript:Payments.getAllItems(WFSMainDoc.getValue("LinkKey"));}]]></xp:this.value>
<xp:button id="buttonEditPayment"
rendered="#{javascript:(WFSMainDoc.isEditable())}">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="panelPaymentsContainer">
<xp:this.action><![CDATA[#{javascript:try{
viewScope.vsRIndex = rIndex;
viewScope.vsShowPayment = true;
break;
}catch(e){
WFSUtils.sysOut("Error in calling dialogPayment " + e.tostring)
}}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<br />
</xp:repeat>
<xp:panel id="panelPaymentInput">
<xp:this.styleClass><![CDATA[#{javascript:(viewScope.vsShowPayment) ? "" : "display=none";}]]></xp:this.styleClass>
<xc:ccTestPaymentInput rendered="#{javascript:(viewScope.vsShowPayment)}">
<xc:this.pItem><![CDATA[#{javascript:try{
var debug:Boolean = true;
if (debug) WFSUtils.sysOut("Open existing row = " + viewScope.vsRIndex)
rIndex = parseInt(viewScope.vsRIndex.toString());
if (debug) WFSUtils.sysOut("rIndex = " + rIndex);
pItem = Payments.getItem(rIndex);
return pItem;
}catch(e){
WFSUtils.sysOut("Failure in Custom Prop of add item " + e.toString());
return null;
}}]]></xc:this.pItem>
</xc:ccTestPaymentInput>
</xp:panel>
</xp:panel><!-- panelPaymentContainer -->
<xp:br></xp:br>
<xp:br></xp:br>
</xp:view>
payment Input Control
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:br></xp:br>
Actual Pay Date: 
<xp:inputText id="actualPayDate"
value="#{compositeData.pItem.actualPayDate}">
<xp:dateTimeHelper id="dateTimeHelper1"></xp:dateTimeHelper>
<xp:this.converter>
<xp:convertDateTime type="date"></xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
<br /> <br />
<xp:button value="Save" id="button1">
<xp:eventHandler event="onclick"
submit="true" refreshMode="partial" refreshId="panelPayments">
<xp:this.action><![CDATA[#{javascript:try{
var debug:Boolean = true;
if (debug) print("Start Payment save");
var pos:Integer = parseInt(viewScope.vsRIndex.toString());
if (debug) print("Working with pos = " + pos + " Call saveThisItem");
if (Payments.saveThisItem(compositeData.pItem , pos)){
if (debug) print("save Payments Worked ");
}else{
if (debug) print("save Payments FAILED ");
}
}catch(e){
print("payment save Error " + e.tostring);
}finally{
viewScope.vsExpPayDate = "";
viewScope.remove("vsShowPayment");
viewScope.remove("vsRIndex");
viewScope.remove("vsGotItem")
}}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:view>

This is all very complicated, and I'm far from understanding what you're trying to achieve here. But at least I found a few oddities in your code:
ad 1: there is a panel with id="panelPaymentContainer" containing a repeat. Inside that repeat is a button doing a partialRefresh on an id="panelPaymentsContainer" >> is this a typo (plural vs. singular forms in "Payment(s))? Should the button be refreshing the panel?
Assuming that this assumption is true: every time you click the button the panel is refreshed together with all its contents, thus also refreshing the repeat's datasource. And so pItem will always be pushed from "outside in" into the content of your repeat. - If the refreshId thing is NOT a typo, then what should it be? I tried hard to read the entire code, but there's a lot of it, so I might have missed something
ad 2: similar thing here: the save button tries to refresh something with an id="panelPayments", but I cannot see anything with this id. So no wonder it doesn't appear to do anything useful.
My recommendation for complicated tasks like these: try to strip everything down to the bare essentials; the more complicated your code is the harder it is to find its mistakes. Start with a panel, a repeat and a few simple controls like a button and a bunch of computed fields to display some test values. Then as soon as this very simple model is working you can start to add to it. - Simplifying also helps others to find mistakes in you concept, btw.

Related

Custom renameParticpant dialogue with "FATALERROR: No input element provided"

I am creating a custom renameParticpant to rename an Eclipse project's launch configuration files, and to change the APPNAME variable in the Makefile. The Makefile side works 100% of the time, but attempting to rename the launch configs causes the following error to occur:
<FATALERROR
FATALERROR: No input element provided
Context: <Unspecified context>
code: none
Data: null
>
This error occurs when the changes are being validated at the following line in org.eclipse.ltk.core.refactoring.PerformChangeOperation [line: 248].
fValidationStatus= fChange.isValid(new SubProgressMonitor(monitor, 1));
Below is a screenshot of the variable view. I suspect that my compositeChange is not in the correct format or is missing some information, however; the error dialogue and logs don't give any helpful information.
Debugger variable view of fChanges
The following is relevant code snippets:
// This one sparks joy (it works great, 100% success)
final HashMap<IFile, TextFileChange> textChanges = new HashMap<IFile, TextFileChange>();
// Stuff gets put inside
textChanges.put(makefile, changeAppname);
// This one does not spark joy (it runs, but results in an invalid Change)
final HashMap<IFile, RenameResourceChange> renameChanges = new HashMap<IFile, RenameResourceChange>();
// Stuff gets put inside
RenameResourceChange renameChange = new RenameResourceChange(
launch.getFile().getProjectRelativePath(), newLaunchName);
renameChanges.put(launch.getFile(), renameChange);
// This is where they get added to the hashmap.
CompositeChange result;
if (textChanges.isEmpty() && renameChanges.isEmpty()) {
result = null;
} else {
result = new CompositeChange(
String.format("Rename project references and dependencies for %1$s", proj.getName()));
for (Iterator<TextFileChange> iter = textChanges.values().iterator(); iter.hasNext();) {
result.add(iter.next());
}
for (Iterator<RenameResourceChange> iter = renameChanges.values().iterator(); iter.hasNext();) {
result.add(iter.next());
}
}
return result;
I looked into adding or generating a changeDescriptor, however that seems like the wrong approach.

What Exception to throw when a web element is found in Selenium Automation [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 10 months ago.
Improve this question
Currently, I am working on a "Selenium Wrapper Library", where a set of methods are created in order to perform automation on a particular Web Portal. These methods includes debug logging and other logic, and are called within test classes.
I've just created a new method to check whether a table cell (tag name td), is present inside a table row (tag name tr). Below is the created method:
public void checkEntryIsNotInTable(String elementTableName, By byElementTable, String checkVisibleText1) {
// Get All Rows from table, using tagname <tr>
List<WebElement> tableRows = getElements(elementTableName, byElementTable);
Debug.log.info("\tTotal of [" + tableRows.size() + "] Rows found in table [" + elementTableName + "]" );
int rowCount = 0;
boolean isNotFound = false;
FINDCELL:
for(WebElement row : tableRows) {
// Get All Cells from table, using tagname <td>
List<WebElement> rowCells = row.findElements(By.tagName("td"));
if(rowCells == null) {
Debug.log.error("\tNo Elements found with TagName [td] in Element [" + byElementTable + "]");
} else {
Debug.log.info("\tRow [" + rowCount++ + "] contains [" + rowCells.size() + "] Cells");
}
// Check Visible Text in Cell, and if found, break from for loop.
for(WebElement cell : rowCells) {
waitFor(2.0);
if(!cell.getText().contains(checkVisibleText1)){
Debug.log.info("\t[" + checkVisibleText1 + "] not found in any Cell.");
isNotFound = true;
break FINDCELL;
}
}
}
// What kind of exception should I throw here!!
if(isNotFound) {
Debug.log.error("\t[" + checkVisibleText1 + "] found in one Cell.");
throw new NoSuchElementException(checkVisibleText1);
}
}
At this stage, when checkVisibleText1 is found, I need to throw a new exception. However, for this method, the exception NoSuchElementException does not reflect a proper exception, since the element is found - and it should not be found.
What exception would be appropriate to throw here?
You should check the available exceptions and:
If you have the appropriate exception that matches your error then use it, else create/use a custom exception or create/use a general exception with a custom message depending on the method.
Always try to output an exception with an message that will be helpful to you.
In this case, assuming checkVisibleText1 is the text you are looking for, using NoSuchElementException with the text as the parameter is not OK.
You should have an exception like ElementDoesNotContainsTextException with a message saying "\t Element [" + elementTableName+ "] does not contain text [" + checkVisibleText1 + "]."
Try to use an appropriate exception when possible or use a general exception with the appropriate message.
My opinion is that you have too much noise/logs in this method, too much logs and too complex for the functionality that it has.
The methods should have their exceptions you you shouldn't need so many logs.
Some solutions:
1. Get the text from the table and check if the text is there
2. Create a selector based on that text with xpath and check for that selector
3. Check for the text in a specific selector
Create reusable methods like: theElementContainsText, theElementDoesNotContainsText
Reuse as much as possible for example for above method(s) you could use other methods that: find element, get element from text

Preventing Long-Running Tables From Clipping Header Image

I'm creating an XSL-FO document in Java. It contains a long table with multiple cells that can, at times, run multiple pages. When it does, it causes the table to clip into an image in our header at the top.
What type of padding do I need to add to prevent our table from clipping into a header image when the clipping occurs mid-table?
We cannot move the header up or down because it is a legal document.
Edit: I'll do my best to include the code from the app, though I'll have to edit it down a bit.
This is our header:
w.write("<fo:static-content flow-name=\"xsl-region-before\">");
w.write("<fo:block-container height=\"1.01in\" width=\"7in\" padding-bottom=\".1in\">");
w.write("<fo:table table-layout=\"fixed\" width=\"7in\">");
w.write("<fo:table-column column-width=\"2.4cm\"/><fo:table-column column-width=\"14cm\"/>");
w.write("<fo:table-body>");
w.write("<fo:table-row>");
w.write("<fo:table-cell number-rows-spanned=\"2\">");
w.write("<fo:block padding-left=\"4mm\">");
w.write("<fo:external-graphic top=\"0cm\" src=\"url('"+this.getResourceUrl("Url.tif")+"')\" width=\"2.4cm\"/>");
w.write("</fo:block>");
w.write("</fo:table-cell>");
w.write("<fo:table-cell>");
w.write("<fo:block font-size=\"10pt\" padding-top=\"4mm\" text-align=\"left\"><fo:inline font-weight=\"bold\">");
w.filteredWrite("SomeCompany");
w.write("</fo:inline></fo:block>");
w.write("<fo:block font-size=\"10pt\" padding-top=\"1mm\" text-align=\"left\"><fo:inline font-weight=\"bold\">");
w.filteredWrite(this.getStuff());
w.write(",</fo:inline> Stuff");
w.write("</fo:block>");
w.write("<fo:block font-size=\"10pt\" padding-top=\"1mm\" padding-bottom=\"1mm\" text-align=\"left\"><fo:inline font-weight=\"bold\">");
w.filteredWrite(this.getAThing());
w.write(",</fo:inline> ");
if (this.getAVariable() != null && this.getAVariableLength().length() > 0)
{
w.write(this.getAVariable());
}
else
{
w.write("TEXT");
}
w.write("</fo:block>");
w.write("</fo:table-cell>");
w.write("</fo:table-row>");
w.write("<fo:table-row>");
w.write("<fo:table-cell border-top-style=\"solid\" border-top-color=\"#000000\" border-top-width=\"0.2mm\" >");
w.write("</fo:table-cell>");
w.write("</fo:table-row>");
w.write("</fo:table-body>");
w.write("</fo:table>");
w.write("</fo:block-container>");
w.write("</fo:static-content>");
}
This is what the initial declaration of our table looks like:
w.write("<fo:table table-layout=\"fixed\" width=\"176mm\">");
w.write("<fo:table-column column-width=\"38mm\"/><fo:table-column column-width=\"38mm\"/>");
w.write("<fo:table-column column-width=\"28mm\"/><fo:table-column column-width=\"27mm\"/>");
w.write("<fo:table-column column-width=\"25mm\"/>");
w.write("<fo:table-column column-width=\"20mm\"/>");
This is what the table header looks like:
w.write("<fo:table-header>");
w.write("<fo:table-row background-color=\"black\" color=\"white\" padding=\"2px\" border-width=\"0.2mm\">");
w.write("<fo:table-cell padding=\"inherit\" border-right-style=\"solid\" border-right-color=\"#000000\" border-right-width=\"0.2mm\">");
w.write("<fo:block text-align=\"left\" font-size=\"10pt\" color=\"white\" font-weight=\"bold\" font-family=\""+font+"\">NameOfColumn</fo:block>");
w.write("</fo:table-cell>");
-Four Additional identical sets of cells-
}
w.write("</fo:table-row>");
w.write("</fo:table-header>");
w.write("<fo:table-body>");
And this is what each additional row looks like when it is initially declared:
w.write("<fo:table-row keep-together=\"always\" padding=\"2px\">");
w.write("<fo:table-cell padding=\"inherit\" number-rows-spanned=" + rowsToSpan+" border-right-style=\"solid\" border-right-color=\"#000000\" border-right-width=\"0.2mm\" border-left-style=\"solid\" border-left-color=\"#000000\" border-left-width=\"0.2mm\" border-bottom-style=\"solid\" border-bottom-color=\"#000000\" border-bottom-width=\"0.2mm\">");
w.write("<fo:block text-align=\"left\" font-size=\"10pt\" font-family=\""+font+"\">");
I've figured out a way to make this work - I simply need to extend the top margin for the Body of my main page master so that the header doesn't overlap my text.
w.write("<fo:simple-page-master master-name=\"main-master\" ");
w.write("page-height=\"11in\" page-width=\"8.5in\" margin-top=\".5in\" ");
w.write("margin-bottom=\".5in\" margin-left=\".5in\" margin-right=\".5in\">");
//w.write("<fo:region-body margin-top=\"20mm\" margin-bottom=\"4in\"/>");
w.write("<fo:region-body margin-top=\"25mm\" margin-bottom=\"4in\"/>");
This means that the top of the page will have a small space between the start of the body and the header, but this is an acceptable compromise for me.

Using ZK: How to add a script into the head tag from java?

Using ZK, I'm trying to add a script into the header tag programmatically.
How can I do this?
Finally I found a solution! Someone in ZK's Forum gives these possible solutions:
http://forum.zkoss.org/question/96845/using-zk-5-how-to-add-a-script-into-the-head-tag-from-java/
"I know two ways for that:
1.Put the declarartion of the javascript file in the lang-addon.xml
lang-addon.xml
<?xml version="1.0" encoding="UTF-8"?>
<language-addon>
. . .
<!-- 4. Path to Bootstrap javascript library -->
<javascript src="~./cyborg/less/bootstrap/js/bootstrap.min.js" type="text/javascript" charset="UTF-8" />
</language-addon>
2. Add manual in java code:
if (view instanceof Window) {
Window win = (Window) view;
PageCtrl pc = (PageCtrl) win.getPage();
pc.addBeforeHeadTags("<script type=\"text/javascript\">" + "(function(i,s,o,g,r,a,m)"
+ "{i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){"
+ "(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();" + "a=s.createElement(o),"
+ "m=s.getElementsByTagName(o)[0];" + "a.async=1;a.src=g;m.parentNode.insertBefore(a,m)" + "})"
+ "(window,document,'script','//www.google-analytics.com/analytics.js','ga');" + "ga('create', "
+ this.trackingID + ", 'auto'); " + "ga('send', 'pageview');" + "</script>");
} else {
throw new UiException("This view model must be applied from a Window component.");
}
from api:
void org.zkoss.zk.ui.sys.PageCtrl.addBeforeHeadTags(String tags)
Adds the tags that will be generated inside the head element and before ZK's default tags. For example,
((PageCtrl)page).addBeforeHeadTags("");
"

How to send content of a file in a tSendMail

i try since some days to send one mail with different informations from child job and father job.
see my jobs below:
and my tRunJob_3
at the end of this job, i can put informations from tAggregateRow in the email, but it send several email (one mail by condition "if" approved DeinitJob --- if --- tRunJob_3)
my file generated by tFileOutputDelimited_1 in the father job contains all the information i need to put in the final mail.
1: how to display these informations in one email (no attachement) ?
2: i have this error in my console:
For input string: "7.91'7.91"
multiple points
what it means ?
EDIT:
with the modification below, it send me 1 email with the informations collected
in my tjavaflex:
code initial
// start part of your Java code
boolean loop ;
System.out.println("## START\n#");
code principal
// here is the main part of the component,
// a piece of code executed in the row
// loop
// code sample:
System.out.println("## LOAD...\n#");
if ((String)globalMap.get("message") != null) {
globalMap.put("message", (String)globalMap.get("message") + row5.mag + " qt: " + row5.qt + " p1: " + row5.p1 + "\n" ) ;
}
code final:
// end of the component, outside/closing the loop
loop = true ;
System.out.println("## END\n#");
with a if loop between tjava and tsendmail
but still have my error:
For input string: "7.91'7.91"
multiple points

Categories