001    /**
002     * Copyright (c) 2000-2013 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.kernel.util.UniqueList;
030    import com.liferay.portal.template.TemplateContextHelper;
031    import com.liferay.portal.theme.ThemeDisplay;
032    import com.liferay.portal.util.PortalUtil;
033    import com.liferay.portal.util.WebKeys;
034    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
035    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
036    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
037    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureServiceUtil;
038    
039    import java.lang.reflect.Field;
040    import java.lang.reflect.Method;
041    
042    import java.util.Collections;
043    import java.util.List;
044    import java.util.Map;
045    
046    import javax.servlet.http.HttpServletRequest;
047    
048    /**
049     * @author Juan Fern??ndez
050     * @author Jorge Ferrer
051     */
052    public class DDMTemplateHelperImpl implements DDMTemplateHelper {
053    
054            @Override
055            public DDMStructure fetchStructure(DDMTemplate template) {
056                    try {
057                            long classNameId = PortalUtil.getClassNameId(DDMStructure.class);
058    
059                            if (template.getClassNameId() == classNameId) {
060                                    return DDMStructureLocalServiceUtil.fetchDDMStructure(
061                                            template.getClassPK());
062                            }
063                    }
064                    catch (Exception e) {
065                    }
066    
067                    return null;
068            }
069    
070            @Override
071            public String getAutocompleteJSON(
072                            HttpServletRequest request, String language)
073                    throws Exception {
074    
075                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
076    
077                    JSONObject typesJSONObject = JSONFactoryUtil.createJSONObject();
078                    JSONObject variablesJSONObject = JSONFactoryUtil.createJSONObject();
079    
080                    for (TemplateVariableDefinition templateVariableDefinition :
081                                    getAutocompleteTemplateVariableDefinitions(request, language)) {
082    
083                            Class<?> clazz = templateVariableDefinition.getClazz();
084    
085                            if (clazz == null) {
086                                    variablesJSONObject.put(
087                                            templateVariableDefinition.getName(), StringPool.BLANK);
088                            }
089                            else {
090                                    if (!typesJSONObject.has(clazz.getName())) {
091                                            typesJSONObject.put(
092                                                    clazz.getName(), getAutocompleteClassJSONObject(clazz));
093                                    }
094    
095                                    variablesJSONObject.put(
096                                            templateVariableDefinition.getName(),
097                                            getAutocompleteVariableJSONObject(clazz));
098                            }
099                    }
100    
101                    jsonObject.put("types", typesJSONObject);
102                    jsonObject.put("variables", variablesJSONObject);
103    
104                    return jsonObject.toString();
105            }
106    
107            @Override
108            public boolean isAutocompleteEnabled(String language) {
109                    if (language.equals(TemplateConstants.LANG_TYPE_FTL) ||
110                            language.equals(TemplateConstants.LANG_TYPE_VM)) {
111    
112                            return true;
113                    }
114    
115                    return false;
116            }
117    
118            protected JSONObject getAutocompleteClassJSONObject(Class<?> clazz) {
119                    JSONObject typeJSONObject = JSONFactoryUtil.createJSONObject();
120    
121                    for (Field field : clazz.getFields()) {
122                            JSONObject fieldJSONObject = getAutocompleteVariableJSONObject(
123                                    field.getType());
124    
125                            typeJSONObject.put(field.getName(), fieldJSONObject);
126                    }
127    
128                    for (Method method : clazz.getMethods()) {
129                            JSONObject methodJSONObject = JSONFactoryUtil.createJSONObject();
130    
131                            JSONArray parametersTypesArray = JSONFactoryUtil.createJSONArray();
132    
133                            Class<?>[] parameterTypes = method.getParameterTypes();
134    
135                            for (Class<?> parameterType : parameterTypes) {
136                                    parametersTypesArray.put(parameterType.getCanonicalName());
137                            }
138    
139                            methodJSONObject.put("argumentTypes", parametersTypesArray);
140    
141                            Class<?> returnTypeClass = method.getReturnType();
142    
143                            methodJSONObject.put("returnType", returnTypeClass.getName());
144    
145                            methodJSONObject.put("type", "Method");
146    
147                            typeJSONObject.put(method.getName(), methodJSONObject);
148                    }
149    
150                    return typeJSONObject;
151            }
152    
153            protected List<TemplateVariableDefinition>
154                            getAutocompleteTemplateVariableDefinitions(
155                                    HttpServletRequest request, String language)
156                    throws Exception {
157    
158                    if (!isAutocompleteEnabled(language)) {
159                            return Collections.emptyList();
160                    }
161    
162                    List<TemplateVariableDefinition> templateVariableDefinitions =
163                            new UniqueList<TemplateVariableDefinition>();
164    
165                    // Declared variables
166    
167                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
168                            WebKeys.THEME_DISPLAY);
169    
170                    DDMTemplate ddmTemplate = (DDMTemplate)request.getAttribute(
171                            WebKeys.DYNAMIC_DATA_MAPPING_TEMPLATE);
172    
173                    long classPK = BeanParamUtil.getLong(ddmTemplate, request, "classPK");
174                    long classNameId = BeanParamUtil.getLong(
175                            ddmTemplate, request, "classNameId");
176    
177                    if (classPK > 0) {
178                            DDMStructure ddmStructure = DDMStructureServiceUtil.getStructure(
179                                    classPK);
180    
181                            classNameId = ddmStructure.getClassNameId();
182                    }
183                    else if (ddmTemplate != null) {
184                            classNameId = ddmTemplate.getClassNameId();
185                    }
186    
187                    Map<String, TemplateVariableGroup> templateVariableGroups =
188                            TemplateContextHelper.getTemplateVariableGroups(
189                                    classNameId, classPK, language, themeDisplay.getLocale());
190    
191                    for (TemplateVariableGroup templateVariableGroup :
192                                    templateVariableGroups.values()) {
193    
194                            if (!templateVariableGroup.isAutocompleteEnabled()) {
195                                    continue;
196                            }
197    
198                            templateVariableDefinitions.addAll(
199                                    templateVariableGroup.getTemplateVariableDefinitions());
200                    }
201    
202                    // Other variables
203    
204                    TemplateResource templateResource = new StringTemplateResource(
205                            _TEMPLATE_ID, _TEMPLATE_CONTENT);
206    
207                    Template template = TemplateManagerUtil.getTemplate(
208                            language, templateResource, false);
209    
210                    for (String key : template.getKeys()) {
211                            Object value = template.get(key);
212    
213                            if (value == null) {
214                                    continue;
215                            }
216    
217                            TemplateVariableDefinition variableDefinition =
218                                    new TemplateVariableDefinition(
219                                            key, value.getClass(), key, (String)null);
220    
221                            templateVariableDefinitions.add(variableDefinition);
222                    }
223    
224                    return templateVariableDefinitions;
225            }
226    
227            protected JSONObject getAutocompleteVariableJSONObject(Class<?> clazz) {
228                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
229    
230                    jsonObject.put("type", clazz.getName());
231    
232                    return jsonObject;
233            }
234    
235            private static final String _TEMPLATE_CONTENT = "# Placeholder";
236    
237            private static final String _TEMPLATE_ID = "0";
238    
239    }