Add a very simple service to test in your application, for instance :
<feature name="services.test"> <extensions> <extension point="org.ametys.web.service.ServiceExtensionPoint" class="org.ametys.web.service.StaticService" id="service.test.password"> <url>service/test-password.html</url> <label i18n="false">Test password</label> <description i18n="false">Test</description> <category i18n="false">Test category</category> <thumbnail> <glyph>ametysicon-development</glyph> </thumbnail> <css> <file plugin="core-ui">font/ametys/AmetysIcon.css</file> </css> <parameters> <parameter name="myString" type="string"> <label i18n="false">String param</label> <description i18n="false">String param</description> </parameter> <parameter name="myPassword" type="password"> <label i18n="false">Password param</label> <description i18n="false">Password param</description> </parameter> </parameters> </extension> </extensions> </feature>
with sitemap.xmap
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"> <map:components> <map:generators> <map:generator name="test-password" src="org.ametys.service.test.TestPasswordServiceGenerator"/> </map:generators> </map:components> <map:pipelines> <map:pipeline> <map:match pattern="service/test-password.html"> <map:generate type="test-password"> <map:parameter name="myString" value="{parent-context-attr:myString}"/> <map:parameter name="myPassword" value="{parent-context-attr:myPassword}"/> </map:generate> <map:serialize type="xhtml"/> </map:match> </map:pipeline> </map:pipelines> </map:sitemap>
and with Generator :
package org.ametys.service.test; import java.io.IOException; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.generation.ServiceableGenerator; import org.apache.cocoon.xml.XMLUtils; import org.xml.sax.SAXException; @SuppressWarnings("javadoc") public class TestPasswordServiceGenerator extends ServiceableGenerator { private static final String __NOT_FILLED = "NOT FILLED"; @Override public void generate() throws IOException, SAXException, ProcessingException { contentHandler.startDocument(); XMLUtils.startElement(contentHandler, "html"); XMLUtils.startElement(contentHandler, "body"); XMLUtils.startElement(contentHandler, "ul"); XMLUtils.createElement(contentHandler, "li", "myString = " + parameters.getParameter("myString", __NOT_FILLED)); XMLUtils.createElement(contentHandler, "li", "myPassword = " + parameters.getParameter("myPassword", __NOT_FILLED)); XMLUtils.endElement(contentHandler, "ul"); XMLUtils.endElement(contentHandler, "body"); XMLUtils.endElement(contentHandler, "html"); contentHandler.endDocument(); } }
Then
- create an instance of your service with values "1" for "Test string" and "2" for "Test password" for instance
- save and close => the params are well-saved => OK
- re-edit the service => change "1" for "1.1" and do not touch the password
- save => the param "myString" is well-saved but the "myPassword" is erased, i.e. was set to an empty string ("")
For the fix, I decided to do the same thing as in org.ametys.runtime.config.ConfigManager#_resolveValue (line 617 of ConfigManager.java)
the line is :
i.e. do a special case of null value with type password
but I think a proper way would to make something (I don't know what) more generic, because it is not the role (in my opinion) of the client code of ElementDefinition API to make this check (it needs another ticket I believe)
but for a first fix, it would do the job I think