001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.dynamicdatamapping.util;
016    
017    import com.liferay.portal.kernel.bean.BeanParamUtil;
018    import com.liferay.portal.kernel.json.JSONArray;
019    import com.liferay.portal.kernel.json.JSONFactoryUtil;
020    import com.liferay.portal.kernel.json.JSONObject;
021    import com.liferay.portal.kernel.template.StringTemplateResource;
022    import com.liferay.portal.kernel.template.Template;
023    import com.liferay.portal.kernel.template.TemplateConstants;
024    import com.liferay.portal.kernel.template.TemplateManagerUtil;
025    import com.liferay.portal.kernel.template.TemplateResource;
026    import com.liferay.portal.kernel.template.TemplateVariableDefinition;
027    import com.liferay.portal.kernel.template.TemplateVariableGroup;
028    import com.liferay.portal.kernel.util.StringPool;
029    import com.liferay.portal.template.TemplateContextHelper;
030    import com.liferay.portal.theme.ThemeDisplay;
031    import com.liferay.portal.util.PortalUtil;
032    import com.liferay.portal.util.WebKeys;
033    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
034    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
035    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
036    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureServiceUtil;
037    
038    import java.lang.reflect.Field;
039    import java.lang.reflect.Method;
040    
041    import java.util.ArrayList;
042    import java.util.Collections;
043    import java.util.LinkedHashSet;
044    import java.util.List;
045    import java.util.Map;
046    import java.util.Set;
047    
048    import javax.servlet.http.HttpServletRequest;
049    
050    /**
051     * @author Juan Fern??ndez
052     * @author Jorge Ferrer
053     */
054    public class DDMTemplateHelperImpl implements DDMTemplateHelper {
055    
056            @Override
057            public DDMStructure fetchStructure(DDMTemplate template) {
058                    try {
059                            long classNameId = PortalUtil.getClassNameId(DDMStructure.class);
060    
061                            if (template.getClassNameId() == classNameId) {
062                                    return DDMStructureLocalServiceUtil.fetchDDMStructure(
063                                            template.getClassPK());
064                            }
065                    }
066                    catch (Exception e) {
067                    }
068    
069                    return null;
070            }
071    
072            @Override
073            public String getAutocompleteJSON(
074                            HttpServletRequest request, String language)
075                    throws Exception {
076    
077                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
078    
079                    JSONObject typesJSONObject = JSONFactoryUtil.createJSONObject();
080                    JSONObject variablesJSONObject = JSONFactoryUtil.createJSONObject();
081    
082                    for (TemplateVariableDefinition templateVariableDefinition :
083                                    getAutocompleteTemplateVariableDefinitions(request, language)) {
084    
085                            Class<?> clazz = templateVariableDefinition.getClazz();
086    
087                            if (clazz == null) {
088                                    variablesJSONObject.put(
089                                            templateVariableDefinition.getName(), StringPool.BLANK);
090                            }
091                            else {
092                                    if (!typesJSONObject.has(clazz.getName())) {
093                                            typesJSONObject.put(
094                                                    clazz.getName(), getAutocompleteClassJSONObject(clazz));
095                                    }
096    
097                                    variablesJSONObject.put(
098                                            templateVariableDefinition.getName(),
099                                            getAutocompleteVariableJSONObject(clazz));
100                            }
101                    }
102    
103                    jsonObject.put("types", typesJSONObject);
104                    jsonObject.put("variables", variablesJSONObject);
105    
106                    return jsonObject.toString();
107            }
108    
109            @Override
110            public boolean isAutocompleteEnabled(String language) {
111                    if (language.equals(TemplateConstants.LANG_TYPE_FTL) ||
112                            language.equals(TemplateConstants.LANG_TYPE_VM)) {
113    
114                            return true;
115                    }
116    
117                    return false;
118            }
119    
120            protected JSONObject getAutocompleteClassJSONObject(Class<?> clazz) {
121                    JSONObject typeJSONObject = JSONFactoryUtil.createJSONObject();
122    
123                    for (Field field : clazz.getFields()) {
124                            JSONObject fieldJSONObject = getAutocompleteVariableJSONObject(
125                                    field.getType());
126    
127                            typeJSONObject.put(field.getName(), fieldJSONObject);
128                    }
129    
130                    for (Method method : clazz.getMethods()) {
131                            JSONObject methodJSONObject = JSONFactoryUtil.createJSONObject();
132    
133                            JSONArray parametersTypesArray = JSONFactoryUtil.createJSONArray();
134    
135                            Class<?>[] parameterTypes = method.getParameterTypes();
136    
137                            for (Class<?> parameterType : parameterTypes) {
138                                    parametersTypesArray.put(parameterType.getCanonicalName());
139                            }
140    
141                            methodJSONObject.put("argumentTypes", parametersTypesArray);
142    
143                            Class<?> returnTypeClass = method.getReturnType();
144    
145                            methodJSONObject.put("returnType", returnTypeClass.getName());
146    
147                            methodJSONObject.put("type", "Method");
148    
149                            typeJSONObject.put(method.getName(), methodJSONObject);
150                    }
151    
152                    return typeJSONObject;
153            }
154    
155            protected List<TemplateVariableDefinition>
156                            getAutocompleteTemplateVariableDefinitions(
157                                    HttpServletRequest request, String language)
158                    throws Exception {
159    
160                    if (!isAutocompleteEnabled(language)) {
161                            return Collections.emptyList();
162                    }
163    
164                    Set<TemplateVariableDefinition> templateVariableDefinitions =
165                            new LinkedHashSet<TemplateVariableDefinition>();
166    
167                    // Declared variables
168    
169                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
170                            WebKeys.THEME_DISPLAY);
171    
172                    DDMTemplate ddmTemplate = (DDMTemplate)request.getAttribute(
173                            WebKeys.DYNAMIC_DATA_MAPPING_TEMPLATE);
174    
175                    long classPK = BeanParamUtil.getLong(ddmTemplate, request, "classPK");
176                    long classNameId = BeanParamUtil.getLong(
177                            ddmTemplate, request, "classNameId");
178    
179                    if (classPK > 0) {
180                            DDMStructure ddmStructure = DDMStructureServiceUtil.getStructure(
181                                    classPK);
182    
183                            classNameId = ddmStructure.getClassNameId();
184                    }
185                    else if (ddmTemplate != null) {
186                            classNameId = ddmTemplate.getClassNameId();
187                    }
188    
189                    Map<String, TemplateVariableGroup> templateVariableGroups =
190                            TemplateContextHelper.getTemplateVariableGroups(
191                                    classNameId, classPK, language, themeDisplay.getLocale());
192    
193                    for (TemplateVariableGroup templateVariableGroup :
194                                    templateVariableGroups.values()) {
195    
196                            if (!templateVariableGroup.isAutocompleteEnabled()) {
197                                    continue;
198                            }
199    
200                            templateVariableDefinitions.addAll(
201                                    templateVariableGroup.getTemplateVariableDefinitions());
202                    }
203    
204                    // Other variables
205    
206                    TemplateResource templateResource = new StringTemplateResource(
207                            _TEMPLATE_ID, _TEMPLATE_CONTENT);
208    
209                    Template template = TemplateManagerUtil.getTemplate(
210                            language, templateResource, false);
211    
212                    for (String key : template.getKeys()) {
213                            Object value = template.get(key);
214    
215                            if (value == null) {
216                                    continue;
217                            }
218    
219                            TemplateVariableDefinition variableDefinition =
220                                    new TemplateVariableDefinition(
221                                            key, value.getClass(), key, (String)null);
222    
223                            templateVariableDefinitions.add(variableDefinition);
224                    }
225    
226                    return new ArrayList<TemplateVariableDefinition>(
227                            templateVariableDefinitions);
228            }
229    
230            protected JSONObject getAutocompleteVariableJSONObject(Class<?> clazz) {
231                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
232    
233                    jsonObject.put("type", clazz.getName());
234    
235                    return jsonObject;
236            }
237    
238            private static final String _TEMPLATE_CONTENT = "# Placeholder";
239    
240            private static final String _TEMPLATE_ID = "0";
241    
242    }