001
014
015 package com.liferay.portlet.dynamicdatamapping.model.impl;
016
017 import com.liferay.portal.LocaleException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.GetterUtil;
022 import com.liferay.portal.kernel.util.HtmlUtil;
023 import com.liferay.portal.kernel.util.ListUtil;
024 import com.liferay.portal.kernel.util.LocaleUtil;
025 import com.liferay.portal.kernel.util.StringBundler;
026 import com.liferay.portal.kernel.util.StringUtil;
027 import com.liferay.portal.kernel.xml.Attribute;
028 import com.liferay.portal.kernel.xml.Document;
029 import com.liferay.portal.kernel.xml.Element;
030 import com.liferay.portal.kernel.xml.Node;
031 import com.liferay.portal.kernel.xml.SAXReaderUtil;
032 import com.liferay.portal.kernel.xml.XPath;
033 import com.liferay.portal.model.CacheField;
034 import com.liferay.portlet.dynamicdatamapping.StructureFieldException;
035 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
036 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
037 import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
038
039 import java.util.HashMap;
040 import java.util.Iterator;
041 import java.util.LinkedHashMap;
042 import java.util.List;
043 import java.util.Locale;
044 import java.util.Map;
045 import java.util.Set;
046 import java.util.concurrent.ConcurrentHashMap;
047
048
051 public class DDMStructureImpl extends DDMStructureBaseImpl {
052
053 public DDMStructureImpl() {
054 }
055
056 public List<String> getAvailableLocales() {
057 Document document = getDocument();
058
059 Element rootElement = document.getRootElement();
060
061 String availableLocales = rootElement.attributeValue(
062 "available-locales");
063
064 return ListUtil.fromArray(StringUtil.split(availableLocales));
065 }
066
067 public String getDefaultLocale() {
068 Document document = getDocument();
069
070 if (document == null) {
071 Locale locale = LocaleUtil.getDefault();
072
073 return locale.toString();
074 }
075
076 Element rootElement = document.getRootElement();
077
078 return rootElement.attributeValue("default-locale");
079 }
080
081 @Override
082 public Document getDocument() {
083 if (_document == null) {
084 try {
085 _document = SAXReaderUtil.read(getXsd());
086 }
087 catch (Exception e) {
088 StackTraceElement[] stackTraceElements = e.getStackTrace();
089
090 for (StackTraceElement stackTraceElement : stackTraceElements) {
091 String className = stackTraceElement.getClassName();
092
093 if (className.endsWith("DDMStructurePersistenceTest")) {
094 return null;
095 }
096 }
097
098 _log.error(e, e);
099 }
100 }
101
102 return _document;
103 }
104
105 public String getFieldDataType(String fieldName)
106 throws StructureFieldException {
107
108 return getFieldProperty(fieldName, "dataType");
109 }
110
111 public String getFieldLabel(String fieldName, Locale locale)
112 throws StructureFieldException {
113
114 return getFieldLabel(fieldName, LocaleUtil.toLanguageId(locale));
115 }
116
117 public String getFieldLabel(String fieldName, String locale)
118 throws StructureFieldException {
119
120 return GetterUtil.getString(
121 getFieldProperty(fieldName, "label", locale), fieldName);
122 }
123
124 public Set<String> getFieldNames() {
125 Map<String, Map<String, String>> fieldsMap = getFieldsMap();
126
127 return fieldsMap.keySet();
128 }
129
130 public String getFieldProperty(String fieldName, String property)
131 throws StructureFieldException {
132
133 return getFieldProperty(fieldName, property, getDefaultLocale());
134 }
135
136 public String getFieldProperty(
137 String fieldName, String property, String locale)
138 throws StructureFieldException {
139
140 if (!hasField(fieldName)) {
141 throw new StructureFieldException();
142 }
143
144 Map<String, Map<String, String>> fieldsMap = _getFieldsMap(locale);
145
146 Map<String, String> field = fieldsMap.get(fieldName);
147
148 return field.get(property);
149 }
150
151 public boolean getFieldRequired(String fieldName)
152 throws StructureFieldException {
153
154 return GetterUtil.getBoolean(getFieldProperty(fieldName, "required"));
155 }
156
157 public Map<String, String> getFields(
158 String fieldName, String attributeName, String attributeValue) {
159
160 return getFields(
161 fieldName, attributeName, attributeValue, getDefaultLocale());
162 }
163
164 public Map<String, String> getFields(
165 String fieldName, String attributeName, String attributeValue,
166 String locale) {
167
168 try {
169 StringBundler sb = new StringBundler(7);
170
171 sb.append("
172 sb.append(HtmlUtil.escapeXPathAttribute(fieldName));
173 sb.append("]
174 sb.append(HtmlUtil.escapeXPath(attributeName));
175 sb.append("=");
176 sb.append(HtmlUtil.escapeXPathAttribute(attributeValue));
177 sb.append("]");
178
179 XPath xPathSelector = SAXReaderUtil.createXPath(sb.toString());
180
181 Node node = xPathSelector.selectSingleNode(getDocument());
182
183 if (node != null) {
184 return _getField(
185 (Element)node.asXPathResult(node.getParent()), locale);
186 }
187 }
188 catch (Exception e) {
189 _log.error(e, e);
190 }
191
192 return null;
193 }
194
195 public Map<String, Map<String, String>> getFieldsMap() {
196 return _getFieldsMap(getDefaultLocale());
197 }
198
199 public Map<String, Map<String, String>> getFieldsMap(String locale) {
200 return _getFieldsMap(locale);
201 }
202
203 public String getFieldType(String fieldName)
204 throws StructureFieldException {
205
206 return getFieldProperty(fieldName, "type");
207 }
208
209 public List<DDMTemplate> getTemplates() throws SystemException {
210 return DDMTemplateLocalServiceUtil.getTemplates(getStructureId());
211 }
212
213 public boolean hasField(String fieldName) {
214 Map<String, Map<String, String>> fieldsMap = getFieldsMap();
215
216 return fieldsMap.containsKey(fieldName);
217 }
218
219 @Override
220 public void prepareLocalizedFieldsForImport(Locale defaultImportLocale)
221 throws LocaleException {
222
223 super.prepareLocalizedFieldsForImport(defaultImportLocale);
224
225 Locale ddmStructureDefaultLocale = LocaleUtil.fromLanguageId(
226 getDefaultLocale());
227
228 try {
229 setXsd(
230 DDMXMLUtil.updateXMLDefaultLocale(
231 getXsd(), ddmStructureDefaultLocale, defaultImportLocale));
232 }
233 catch (Exception e) {
234 throw new LocaleException(e);
235 }
236 }
237
238 @Override
239 public void setDocument(Document document) {
240 _document = document;
241 }
242
243 public void setLocalizedFieldsMap(
244 Map<String, Map<String, Map<String, String>>> localizedFieldsMap) {
245
246 _localizedFieldsMap = localizedFieldsMap;
247 }
248
249 @Override
250 public void setXsd(String xsd) {
251 super.setXsd(xsd);
252
253 _document = null;
254 _localizedFieldsMap.clear();
255 }
256
257 private Map<String, String> _getField(Element element, String locale) {
258 Map<String, String> field = new HashMap<String, String>();
259
260 List<String> availableLocales = getAvailableLocales();
261
262 if ((locale != null) && !availableLocales.contains(locale)) {
263 locale = getDefaultLocale();
264 }
265
266 String xPathExpression =
267 "meta-data[@locale=\"".concat(locale).concat("\"]");
268
269 XPath xPathSelector = SAXReaderUtil.createXPath(xPathExpression);
270
271 Node node = xPathSelector.selectSingleNode(element);
272
273 Element metaDataElement = (Element)node.asXPathResult(node.getParent());
274
275 if (metaDataElement != null) {
276 List<Element> childMetaDataElements = metaDataElement.elements();
277
278 for (Element childMetaDataElement : childMetaDataElements) {
279 String name = childMetaDataElement.attributeValue("name");
280 String value = childMetaDataElement.getText();
281
282 field.put(name, value);
283 }
284 }
285
286 for (Attribute attribute : element.attributes()) {
287 field.put(attribute.getName(), attribute.getValue());
288 }
289
290 return field;
291 }
292
293 private Map<String, Map<String, String>> _getFieldsMap(String locale) {
294 Map<String, Map<String, String>> fieldsMap = _localizedFieldsMap.get(
295 locale);
296
297 if (fieldsMap == null) {
298 fieldsMap = new LinkedHashMap<String, Map<String, String>>();
299
300 XPath xPathSelector = SAXReaderUtil.createXPath(
301 "
302
303 List<Node> nodes = xPathSelector.selectNodes(getDocument());
304
305 Iterator<Node> itr = nodes.iterator();
306
307 while (itr.hasNext()) {
308 Element element = (Element)itr.next();
309
310 String name = element.attributeValue("name");
311
312 fieldsMap.put(name, _getField(element, locale));
313 }
314
315 _localizedFieldsMap.put(locale, fieldsMap);
316 }
317
318 return fieldsMap;
319 }
320
321 private static Log _log = LogFactoryUtil.getLog(DDMStructureImpl.class);
322
323 @CacheField
324 private Document _document;
325
326 private Map<String, Map<String, Map<String, String>>> _localizedFieldsMap =
327 new ConcurrentHashMap<String, Map<String, Map<String, String>>>();
328
329 }