XStream fromXML with dynamic inner structure - xml-parsing

I have XML object that I want converted back into the objects but am having trouble doing it with XStream. The problem with it is that the "RESULT" tag is different from different API services, so not sure how to alias it for different classes. The example below would be for a LOGIN service example. I may have another service that has the same Envelope/Body/RESULT/ but different attributes within it, i.e. Logout. Not sure how to go about leveraging the Envelope and Body to reduce redundent code.
<Envelope>
<Body>
<RESULT>
<SUCCESS>true</SUCCESS>
<SESSIONID>1320948a32098</SESSIONID>
<ORGANIZATION_ID>1</ORGANIZATION_ID>
</RESULT>
</Body>
</Envelope>
I have currently created classes for EnvelopeResponse, BodyResponse and a ResultResponse class I'll want all my other classes extending from? Is that the way to go about it? i.e. My LoginResponse class extends from ResultResponse.class, same for LogoutResponse.
I tried
xStream = new Xstream();
xStream.alias("Envelope", EnvelopeResponse.class);
xStream.alias("Body", BodyResponse.class);
xStream.alias("RESULT", LoginResponse.class); //Dynamic based on what API I'd like in the RESULT
Please help.

Since you are having multiple services, adding one more level of abstraction would be a good idea.
i.e.
<Envelope>
<Body>
<RESULT>
<LOGINRESPONSE>
<SUCCESS>true</SUCCESS>
<SESSIONID>1320948a32098</SESSIONID>
<ORGANIZATION_ID>1</ORGANIZATION_ID>
</LOGINRESPONSE>
</RESULT>
</Body>
</Envelope>
<Envelope>
<Body>
<RESULT>
<LOGOUT>
<SUCCESS>true</SUCCESS>
</LOGOUT>
</RESULT>
</Body>
</Envelope>
You can then alias these service responses to different classes,
xStream.alias("LOGOUT", LOGOUT.class);
xStream.alias("LOGINRESPONSE", LOGINRESPONSE.class);

Related

Sending multiple emails from within Orbeon Forms

On Orbeon Forms 4.8, I've rebuilt email-form.xpl so that it constructs different emails depending on various conditions in the form. That works nicely, and it's even embedding form information in the emails it creates. I've got to the point where I have created a nicely structured set of structures, as expected by the Orbeon Email processor. They are all wrapped up in a tag, so I have something like ....
When it comes to actually calling the email processor, I need to work through that XML structure calling the email processor for one message at a time. The code below is what I have to do this and I can see from the debug that it is receiving my messages correctly, but once I check inside the processor all of the XML tags have been stripped away, and the email processor won't accept the input (which I know would only send the first message if it worked at all) because it says it is an incomplete content model.
<p:processor name="oxf:pipeline">
<p:input
name="config"
href="#messages"
transform="oxf:unsafe-xslt"
debug="LOOPING THROUGH EMAIL MESSAGES - MESSAGES">
<p:config xsl:version="2.0">
<p:param type="input" name="messages"/>
<xsl:message>
XXXXX
<xsl:value-of select="messages/message"/>
XXXXX
</xsl:message>
<xsl:for-each select="/*/message">
<p:processor name="oxf:email">
<p:input name="data">
<message>
<xsl:value-of select="messages/message"/>
</message>
</p:input>
</p:processor>
</xsl:for-each>
</p:config>
</p:input>
</p:processor>
Clearly I did something wrong, but I don't see what it was.
To print the XML via XSLT, use <xsl:copy-of> instead of <xsl:value-of>. The latter always takes the string value of the XML, which only looks at the text nodes. The former makes a copy of the XML tree.
The email processor can only send one email at a time. So What's needed is iterating over the <message> elements you have created via XSLT. The iteration must be done in XPL, so you must use <p:for-each>.

Request scope issue in IBM portal 8.0

I have a JSR 286 portlet running in a Websphere Portal Server 8.0. There, I do a file upload and after show the results of processing. Initially my managed bean responsible to process this file has a Request Scope (#RequestScoped). When I Click in command button to upload file, the method in MB process correctly and fills a collection of results (dadosCarga attribute in MB below) that must be showed in JSP page. However, when I the page is rederized I got a stacktrace explaining that my Managed Bean class was not found (ClassNotFoundException) and results are not shown. I got the same results using ViewScoped. Just when I changed scope from Request to Session (#SessionScoped), the results are shown.
After I googled for some answer, I found this page explaining about difference between action and render request in Portlets. It was suggested to use JSF Portlet bridge. However, this page is not active anymore. There is a Portlet bridge for Apache Myfaces (IBM portal runs over MyFaces). However, I could not see how use it. Is it just put both jars (api and implementation) in WEB-INF/lib? I tried, but I got a exception when I tried load the pages in application. So I remove them.
Below, I show My Portlet configuration, Managed Bean and JSP page. Is there any alternative, a better Idea about how to deal with this? Or may be a explanation about how to use correclty MyFaces Bridge (I could not found none in its home page).
Thanks,
Rafael Afonso
Portlet configuration:
<portlet>
<portlet-name>CargaUsuarios</portlet-name>
<display-name>CargaUsuarios</display-name>
<portlet-class>com.ibm.faces20.portlet.FacesPortlet</portlet-class>
<init-param>
<name>com.ibm.faces.portlet.page.view</name>
<value>/pages/carga/cargaUsuarios.jsp</value>
</init-param>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<portlet-info>
<title>Carga de Usuarios</title>
<short-title>Carga deUsuarios</short-title>
<keywords>Carga Usuario</keywords>
</portlet-info>
</portlet>
Manged Bean:
#ManagedBean(name = "cargaUsuariosMB")
#RequestScoped
public class CargaUsuariosMB extends AbstractMB {
private String nomeArquivo; // FIle name
private Collection<CargaUsuarioInfoBean> dadosCarga; // processing result.
public String doUploadArquivo() {
this.dadosCarga = ... // process file and receives a collection
this.nomeArquivo = ... // get uploaded file name
return null; // Return to same origin page
}
// Getters...
}
JSP page (cargaUsuarios.jsp):
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%#taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%#taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>
<%#taglib
uri="http://www.ibm.com/xmlns/prod/websphere/portal/v6.1/portlet-client-model"
prefix="portlet-client-model"%>
<%#page language="java" contentType="text/html"
pageEncoding="ISO-8859-1" session="false"%>
<portlet:defineObjects />
<portlet-client-model:init>
<portlet-client-model:require module="ibm.portal.xml.*" />
<portlet-client-model:require module="ibm.portal.portlet.*" />
</portlet-client-model:init>
<f:view>
<h2>Carga de Usuários</h2>
<h:form enctype="multipart/form-data">
<p>
<label for="arquivoCarga"> <span>File:</span> </label> <input
type="file" name="arquivoCarga" id="FileCarga" />
</p>
<br />
<br />
<h:commandButton value="Salvar File"
action="#{cargaUsuariosMB.doUploadArquivo}"></h:commandButton>
</h:form>
<h:panelGroup id="pnlProcessamento"
rendered="#{not empty cargaUsuariosMB.dadosCarga }">
<h:outputText
value="Dados do File #{cargaUsuariosMB.nomeArquivo} processados com sucesso."></h:outputText>
<br />
<h:dataTable id="tblDadosProcessamento"
columnClasses="numLinha,cpf,status"
value="#{cargaUsuariosMB.dadosCarga}" var="dadosCarga"
styleClass="dadosProcessamento" width="100%" border="1">
<%-- Show processing results. --%>
</h:dataTable>
</h:panelGroup>
<h:messages styleClass="messages" id="msgsPesquisaCadastro"
errorClass="mensagensErro" errorStyle="color: red;"></h:messages>
</f:view>
Please try adding the following in the portlet.xml and see if it works:
<container-runtime-option>
<name>javax.portlet.actionScopedRequestAttributes</name>
<value>true</value>
</container-runtime-option>
For more information please download and check the following section in Portlet V2.0 specification:
PLT.10.4.4 Runtime Option
javax.portlet.actionScopedRequestAttributes
You are right about the render and action request, JSF (or CDI) Request and ViewScoped doesn't work properly. But solution could be using JBoss Portlet Bridge which contains brand new scopes - PortletLifecycleScoped and PortletRedisplayScoped. The first will behave exactly like a RequestScope, you will find more info in the docs. However, I am not sure if will able to use these scopes in other portals except GateIn.
When you use request scope, the data needs to be carried from portlet action to portlet render phase. The data is normally carried for request scoped beans via the portlet render parameters are a String. In order to get your data saved there, your object needs to be Serializable.
Besides that, you might want to upgrade your WebSphere Application Server beneath the WebSphere Portal to version 8.0.0.6 to avoid PM79460 and Portal itself to the latest FixPack as well.
Hope this helps.
BTW: JSR286 and JEE6 do not specify how CDI shall interact with the Portlet programming model. You might want to look at JSR362 for that.
IBM uses its own portlet bridge. It is not recommended to use any bridges in addition to that.

How to get the language specific messages using google closure template

Am trying to implement internationalization support to my project for this people suggested google Closure Templates.but am very new to closure templates.am trying to get the language specific messages using closure template but am not getting in xlf file.If any one knows how to generate language specific messages using closure template, please tell me the steps.that's great help to me.
My .soy file code as bellow.
{namespace poc}
/**
*Testing message translation
*#param pageTitle
*/
{template .translate}
<HTML>
<Head>
<title>{$pageTitle}
</title>
</head>
<div>
{msg desc="Hello"}Hello{/msg}
</div>
</html>
{/template}
and generated .xlf content as bellow
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file original="SoyMsgBundle" datatype="x-soy-msg-bundle" xml:space="preserve" source-language="en" target-language="pt-BR">
<body>
<trans-unit id="2286494898080570401" datatype="html">
<source>Thanks</source>
<target/>
<note priority="1" from="description">Says thanks</note>
</trans-unit>
</body>
</file>
</xliff>
I see you already used the SoyMsgExtractor to create the base xlf. Next you need to make translations of this base xlf to the languages you want to support. A file for each language is created. I used the xliff exitor from Translution. http://sourceforge.net/projects/eviltrans.
Next, using the SoyToJsSrcCompiler a translation soy can be made per language:
java -jar SoyToJsSrcCompiler.jar --shouldGenerateGoogMsgDefs --bidiGlobalDir 1 --messageFilePathFormat Filename_en-us.xliff --outputPathFormat FileName_fr.js *.soy
This will create a Filename._fr.js file that contains the compiled soy file.
Including this file instead of the original soy (or compiled) will create a localized version.
Good luck!
\Rene
i think the easiest way is to make (i.e. generate from whatever source) a separate js file which contains one messages object and reference it through an extern declared function.
it justs works and has no complicated dependencies.

Ignore the slash in Magento <url>

I’ve created a menu in page.xml and it looks like this:
<reference name="primary.menu">
<action method="addLink" translate="label title">
<label>Test</label>
<url>test.html</url>
<title>Test</title>
<prepare>1</prepare>
<urlParams/>
<position>10</position>
<liParams>dark-gray</liParams>
<aParams></aParams>
<beforeText></beforeText>
<afterText></afterText>
</action>
...................
The class used for the primary.menu block is extending the Mage_Page_Block_Template_Links class from Magento’s core.
The problem is, that when I click this link it goes to ‘www.mydomain.com/test.html/’ which is not working. My question is what should I do in order to stop the last ‘/’ from showing in the url?
I think that <prepare>1</prepare> is building your URL query (in the absence of a dedicated helper to supply the URL) and as a result is prefixing your URL with the domain (which is what you want), but it is also appending a trailing slash (which is what you don't want)
Either create a helper to supply the "proper" URL.
If the page is a Magento CMS page, use that helper (preferred)
Use <prepare/> and <url>/test.html</url> (hack alert!)
To use a Magento CMS helper to add a link
<action method="addLink" translate="label title before_text" module="cms">
<label>Test</label>
<url helper="cms/page/getPageUrl">
<page_id>1</page_id>
</url>
<title>Test</title>
<prepare/>
<urlParams/>
<position>10</position>
<li/>
<a/>
<before_text/>
<after_text/>
</action>

additional parameters in magento's customer.xml layout file

i'm trying to add some explanatory text to the top customer links (my account, my cart etc) via the customer.xml file from the blank theme (this is in Magento 1.4.1.1)
i think that magento has the capability out of the box by issuing afterText or beforeText parameters, but when i use them it only seems to shove things before the link (not after, which is what I'm after).
here's an extract from customer.xml that includes the additional < afterText > parameter:
<default>
<!-- Mage_Customer -->
<reference name="top.links">
<action method="addLink" translate="label title" module="customer"><label>Your Account</label><url helper="customer/getAccountUrl"/><title>Your Account</title><prepare/><urlParams/><position>10</position><null /><aParams>rel="nofollow"</aParams><afterText>click to login</afterText></action>
</reference>
</default>
has anyone had any luck with this before? does it need some additional arguments for liParams?
thanks in advance!
EDIT: here's the final code that seems to be working for me. Note the addition of the extra fields as suggested by
thanks for this, it helped a lot. both you and #Zyava answer below helped me sort it out.
There's one field missing from your suggestion above (the innerText field). I've put the full code below that looks to be working for me. hope it helps someone else!
<action method="addLink" translate="label title" module="customer">
<label>Your Account</label>
<url helper="customer/getAccountUrl"/>
<title>Your Account</title>
<prepare/>
<urlParams/>
<liParams/>
<aParams>rel="nofollow"</aParams>
<innerText/>
<beforeText>yourbeforetext</beforeText>
<afterText>youraftertext</afterText></action>
big thank you to #clockworkgeek and #zyava - both of your answers helped me get through this.
Unfortunately the XML tag names don't relate to the variable parameters, it is the number of parameters that matters. You need to specify all parameters up to afterText including beforeText.
<action method="addLink" translate="label title" module="customer">
<label>Your Account</label>
<url helper="customer/getAccountUrl"/>
<title>Your Account</title>
<prepare/>
<urlParams/>
<position>10</position>
<liParams/>
<aParams>rel="nofollow"</aParams>
<beforeText/>
<afterText>click to login</afterText>
</action>
Block 'top.links' has type Mage_Page_Block_Template_Links. Look at Mage_Page_Block_Template_Links::addLink() method:
public function addLink($label, $url='', $title='', $prepare=false, $urlParams=array(),
$position=null, $liParams=null, $aParams=null, $beforeText='', $afterText='')
{
As we can see, $afterText parameter exists here. Now go to your theme's page/template/links.phtml, in my case it is \app\design\frontend\base\default\template\page\template\links.phtml and check that something like <?php echo $_link->getAfterText() ?> is present there.

Resources