Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
import java.util.Collections;
import javax.servlet.ServletException;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonGenerator.Feature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractValidatorServlet extends SlingSafeMethodsServlet {
private static final Logger LOG = LoggerFactory.getLogger(AbstractValidatorServlet.class);
private static final JsonFactory FACTORY = new JsonFactory().disable(Feature.AUTO_CLOSE_TARGET);
private static final ObjectMapper MAPPER = new ObjectMapper();
protected final void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response)
throws ServletException, IOException {
final String value = request.getRequestParameter("value").getString();
final String path = request.getResource().getPath();
final boolean valid = isValid(request, path, value);
try {
final JsonGenerator generator = FACTORY.createJsonGenerator(response.getWriter());
MAPPER.writeValue(generator, Collections.singletonMap("valid", valid));
} catch (final JsonGenerationException jge) {
LOG.error("error generating JSON response", jge);
} catch (final JsonMappingException jme) {
LOG.error("error mapping JSON response", jme);
} catch (final IOException ioe) {
LOG.error("error writing JSON response", ioe);
* Validate the given value for this request and path.
* @param request servlet request
* @param path path to current component being validated
* @param value input value to validate
* @return true if value is valid, false otherwise
protected abstract boolean isValid(final SlingHttpServletRequest request, final String path, final String value);
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="" xmlns:jcr="" xmlns:nt=""
jcr:primaryType="cq:Dialog" xtype="dialog">
<items jcr:primaryType="cq:WidgetCollection">
<tabs jcr:primaryType="cq:TabPanel">
<items jcr:primaryType="cq:WidgetCollection">
<first jcr:primaryType="nt:unstructured" title="Form" xtype="panel">
<items jcr:primaryType="cq:WidgetCollection">
<name jcr:primaryType="cq:Widget" fieldLabel="Name" name="./name" xtype="textfield" allowBlank="{Boolean}false"
validator="function(value) {
var dialog = this.findParentByType('dialog');
var url = CQ.HTTP.addParameter(dialog.path + '.validator.json', 'value', value);
var result = CQ.HTTP.eval(url);
return result.valid ? true : 'Form name already exists on this page.';
}" />
import java.util.HashMap;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Property(name = "sling.servlet.resourceTypes", value = FormsConstants.RT_FORM_BEGIN),
@Property(name = "sling.servlet.extensions", value = "json"),
@Property(name = "sling.servlet.methods", value = "GET"),
@Property(name = "sling.servlet.selectors", value = "validator"),
@Property(name = "service.description", value = "Form Validator Servlet")
public final class FormValidatorServlet extends AbstractValidatorServlet {
private static final Logger LOG = LoggerFactory.getLogger(FormValidatorServlet.class);
protected boolean isValid(final SlingHttpServletRequest request, final String path, final String value) {
final Map<String, String> names = getFormNames(request);
// ensure that form name is unique among all forms defined on this page
// (except for itself)
return !names.containsKey(value) || names.get(value).equals(path);
private Map<String, String> getFormNames(final SlingHttpServletRequest request) {
final Map<String, String> names = new HashMap<String, String>();
final Node currentNode = request.getResource().adaptTo(Node.class);
try {
final Node par = currentNode.getParent();
final NodeIterator nodes = par.getNodes();
// get all form names for the current paragraph system
while (nodes.hasNext()) {
final Node node = nodes.nextNode();
if (isFormStart(node)) {
final String name = node.getProperty(FormsConstants.ELEMENT_PROPERTY_NAME).getString();
names.put(name, node.getPath());
} catch (final RepositoryException re) {
LOG.error("error getting form names", re);
return names;
private boolean isFormStart(final Node node) throws RepositoryException {
return node.hasProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY)
&& FormsConstants.RT_FORM_BEGIN.equals(node.getProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY).getString())
&& node.hasProperty(FormsConstants.ELEMENT_PROPERTY_NAME);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.