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