/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.dynamic.data.mapping.form.renderer.internal;
import com.liferay.dynamic.data.mapping.form.field.type.BaseDDMFormFieldRenderer;
import com.liferay.dynamic.data.mapping.form.field.type.DDMFormFieldRenderer;
import com.liferay.dynamic.data.mapping.form.renderer.DDMFormRenderer;
import com.liferay.dynamic.data.mapping.form.renderer.DDMFormRenderingContext;
import com.liferay.dynamic.data.mapping.form.renderer.DDMFormRenderingException;
import com.liferay.dynamic.data.mapping.form.renderer.DDMFormTemplateContextFactory;
import com.liferay.dynamic.data.mapping.model.DDMForm;
import com.liferay.dynamic.data.mapping.model.DDMFormLayout;
import com.liferay.dynamic.data.mapping.util.DDM;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
import com.liferay.portal.kernel.json.JSONFactory;
import com.liferay.portal.kernel.json.JSONSerializer;
import com.liferay.portal.kernel.template.Template;
import com.liferay.portal.kernel.template.TemplateConstants;
import com.liferay.portal.kernel.template.TemplateException;
import com.liferay.portal.kernel.template.TemplateManagerUtil;
import com.liferay.portal.kernel.template.TemplateResource;
import com.liferay.portal.kernel.template.URLTemplateResource;
import com.liferay.portal.kernel.util.MapUtil;
import java.io.Writer;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
/**
* @author Marcellus Tavares
*/
@Component(
immediate = true, property = {"templatePath=/META-INF/resources/form.soy"}
)
public class DDMFormRendererImpl implements DDMFormRenderer {
@Override
public String render(
DDMForm ddmForm, DDMFormLayout ddmFormLayout,
DDMFormRenderingContext ddmFormRenderingContext)
throws DDMFormRenderingException {
try {
return doRender(ddmForm, ddmFormLayout, ddmFormRenderingContext);
}
catch (DDMFormRenderingException ddmfre) {
throw ddmfre;
}
catch (PortalException pe) {
throw new DDMFormRenderingException(pe);
}
}
@Override
public String render(
DDMForm ddmForm, DDMFormRenderingContext ddmFormRenderingContext)
throws DDMFormRenderingException {
try {
return doRender(
ddmForm, _ddm.getDefaultDDMFormLayout(ddmForm),
ddmFormRenderingContext);
}
catch (DDMFormRenderingException ddmfre) {
throw ddmfre;
}
catch (PortalException pe) {
throw new DDMFormRenderingException(pe);
}
}
@Activate
protected void activate(Map<String, Object> properties) {
String templatePath = MapUtil.getString(properties, "templatePath");
TemplateResource formTemplateResource = getFormTemplateResource(
templatePath);
_templateResources.add(formTemplateResource);
}
@Reference(
cardinality = ReferenceCardinality.MULTIPLE,
policy = ReferencePolicy.DYNAMIC,
policyOption = ReferencePolicyOption.GREEDY,
unbind = "removeDDMFormFieldRenderer"
)
protected void addDDMFormFieldRenderer(
DDMFormFieldRenderer ddmFormFieldRenderer) {
TemplateResource templateResource = getTemplateResource(
ddmFormFieldRenderer);
if (templateResource != null) {
_templateResources.add(templateResource);
}
}
protected String doRender(
DDMForm ddmForm, DDMFormLayout ddmFormLayout,
DDMFormRenderingContext ddmFormRenderingContext)
throws PortalException {
Template template = TemplateManagerUtil.getTemplate(
TemplateConstants.LANG_TYPE_SOY, _templateResources, false);
populateCommonContext(
template, ddmForm, ddmFormLayout, ddmFormRenderingContext);
String templateNamespace = (String)template.get("templateNamespace");
String html = render(template, templateNamespace);
String javaScript = render(template, "ddm.form_renderer_js");
return html.concat(javaScript);
}
protected TemplateResource getFormTemplateResource(String templatePath) {
Class<?> clazz = getClass();
ClassLoader classLoader = clazz.getClassLoader();
URL templateURL = classLoader.getResource(templatePath);
return new URLTemplateResource(templateURL.getPath(), templateURL);
}
protected TemplateResource getTemplateResource(
DDMFormFieldRenderer ddmFormFieldRenderer) {
if (ddmFormFieldRenderer instanceof BaseDDMFormFieldRenderer) {
BaseDDMFormFieldRenderer baseDDMFormFieldRenderer =
(BaseDDMFormFieldRenderer)ddmFormFieldRenderer;
return baseDDMFormFieldRenderer.getTemplateResource();
}
return null;
}
protected TemplateResource getTemplateResource(String templatePath) {
Class<?> clazz = getClass();
ClassLoader classLoader = clazz.getClassLoader();
URL templateURL = classLoader.getResource(templatePath);
return new URLTemplateResource(templateURL.getPath(), templateURL);
}
protected void populateCommonContext(
Template template, DDMForm ddmForm, DDMFormLayout ddmFormLayout,
DDMFormRenderingContext ddmFormRenderingContext)
throws PortalException {
Map<String, Object> ddmFormTemplateContext =
_ddmFormTemplateContextFactory.create(
ddmForm, ddmFormLayout, ddmFormRenderingContext);
template.putAll(ddmFormTemplateContext);
ddmFormTemplateContext.remove("fieldTypes");
JSONSerializer jsonSerializer = _jsonFactory.createJSONSerializer();
template.put(
"context", jsonSerializer.serializeDeep(ddmFormTemplateContext));
}
protected void removeDDMFormFieldRenderer(
DDMFormFieldRenderer ddmFormFieldRenderer) {
TemplateResource templateResource = getTemplateResource(
ddmFormFieldRenderer);
if (templateResource != null) {
_templateResources.remove(templateResource);
}
}
protected String render(Template template, String namespace)
throws TemplateException {
Writer writer = new UnsyncStringWriter();
template.put(TemplateConstants.NAMESPACE, namespace);
template.put(TemplateConstants.RENDER_STRICT, Boolean.FALSE);
template.processTemplate(writer);
return writer.toString();
}
@Reference
private DDM _ddm;
@Reference
private DDMFormTemplateContextFactory _ddmFormTemplateContextFactory;
@Reference
private JSONFactory _jsonFactory;
private final List<TemplateResource> _templateResources =
new CopyOnWriteArrayList<>();
}