001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.dynamicdatamapping.model.impl;
016    
017    import com.liferay.portal.LocaleException;
018    import com.liferay.portal.kernel.configuration.Filter;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.util.ArrayUtil;
024    import com.liferay.portal.kernel.util.GetterUtil;
025    import com.liferay.portal.kernel.util.HtmlUtil;
026    import com.liferay.portal.kernel.util.ListUtil;
027    import com.liferay.portal.kernel.util.LocaleUtil;
028    import com.liferay.portal.kernel.util.PredicateFilter;
029    import com.liferay.portal.kernel.util.PropsKeys;
030    import com.liferay.portal.kernel.util.PropsUtil;
031    import com.liferay.portal.kernel.util.StringBundler;
032    import com.liferay.portal.kernel.util.StringPool;
033    import com.liferay.portal.kernel.util.StringUtil;
034    import com.liferay.portal.kernel.util.Validator;
035    import com.liferay.portal.kernel.xml.Attribute;
036    import com.liferay.portal.kernel.xml.Document;
037    import com.liferay.portal.kernel.xml.Element;
038    import com.liferay.portal.kernel.xml.Node;
039    import com.liferay.portal.kernel.xml.SAXReaderUtil;
040    import com.liferay.portal.kernel.xml.XPath;
041    import com.liferay.portal.model.CacheField;
042    import com.liferay.portal.model.Group;
043    import com.liferay.portal.service.GroupLocalServiceUtil;
044    import com.liferay.portal.theme.ThemeDisplay;
045    import com.liferay.portal.util.PortalUtil;
046    import com.liferay.portal.util.PropsValues;
047    import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
048    import com.liferay.portlet.dynamicdatamapping.StructureFieldException;
049    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
050    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
051    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
052    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
053    import com.liferay.portlet.dynamicdatamapping.util.DDMXMLUtil;
054    
055    import java.util.ArrayList;
056    import java.util.HashMap;
057    import java.util.LinkedHashMap;
058    import java.util.List;
059    import java.util.Locale;
060    import java.util.Map;
061    import java.util.Set;
062    import java.util.concurrent.ConcurrentHashMap;
063    
064    /**
065     * @author Brian Wing Shun Chan
066     */
067    public class DDMStructureImpl extends DDMStructureBaseImpl {
068    
069            @Override
070            public String[] getAvailableLanguageIds() {
071                    Document document = getDocument();
072    
073                    Element rootElement = document.getRootElement();
074    
075                    String availableLocales = rootElement.attributeValue(
076                            "available-locales");
077    
078                    return StringUtil.split(availableLocales);
079            }
080    
081            @Override
082            public List<String> getChildrenFieldNames(String fieldName)
083                    throws PortalException, SystemException {
084    
085                    List<String> fieldNames = new ArrayList<String>();
086    
087                    Map<String, Map<String, String>> fieldsMap = getFieldsMap(true);
088    
089                    for (Map<String, String> field : fieldsMap.values()) {
090                            String parentNameKey = _getPrivateAttributeKey("parentName");
091    
092                            String parentName = field.get(parentNameKey);
093    
094                            if (fieldName.equals(parentName)) {
095                                    fieldNames.add(field.get("name"));
096                            }
097                    }
098    
099                    return fieldNames;
100            }
101    
102            @Override
103            public String getCompleteXsd() throws PortalException, SystemException {
104                    if (getParentStructureId() == 0) {
105                            return getXsd();
106                    }
107    
108                    DDMStructure parentStructure =
109                            DDMStructureLocalServiceUtil.getStructure(getParentStructureId());
110    
111                    return _mergeXsds(getXsd(), parentStructure.getCompleteXsd());
112            }
113    
114            @Override
115            public String getDefaultLanguageId() {
116                    Document document = getDocument();
117    
118                    if (document == null) {
119                            Locale locale = LocaleUtil.getSiteDefault();
120    
121                            return locale.toString();
122                    }
123    
124                    Element rootElement = document.getRootElement();
125    
126                    return rootElement.attributeValue("default-locale");
127            }
128    
129            @Override
130            public Document getDocument() {
131                    if (_document == null) {
132                            try {
133                                    _document = SAXReaderUtil.read(getXsd());
134                            }
135                            catch (Exception e) {
136                                    StackTraceElement[] stackTraceElements = e.getStackTrace();
137    
138                                    for (StackTraceElement stackTraceElement : stackTraceElements) {
139                                            String className = stackTraceElement.getClassName();
140    
141                                            if (className.endsWith("DDMStructurePersistenceTest")) {
142                                                    return null;
143                                            }
144                                    }
145    
146                                    _log.error(e, e);
147                            }
148                    }
149    
150                    return _document;
151            }
152    
153            @Override
154            public String getFieldDataType(String fieldName)
155                    throws PortalException, SystemException {
156    
157                    return getFieldProperty(fieldName, "dataType");
158            }
159    
160            @Override
161            public String getFieldLabel(String fieldName, Locale locale)
162                    throws PortalException, SystemException {
163    
164                    return getFieldLabel(fieldName, LocaleUtil.toLanguageId(locale));
165            }
166    
167            @Override
168            public String getFieldLabel(String fieldName, String locale)
169                    throws PortalException, SystemException {
170    
171                    return GetterUtil.getString(
172                            getFieldProperty(fieldName, "label", locale), fieldName);
173            }
174    
175            @Override
176            public Set<String> getFieldNames() throws PortalException, SystemException {
177                    Map<String, Map<String, String>> fieldsMap = getFieldsMap();
178    
179                    return fieldsMap.keySet();
180            }
181    
182            @Override
183            public String getFieldProperty(String fieldName, String property)
184                    throws PortalException, SystemException {
185    
186                    return getFieldProperty(fieldName, property, getDefaultLanguageId());
187            }
188    
189            @Override
190            public String getFieldProperty(
191                            String fieldName, String property, String locale)
192                    throws PortalException, SystemException {
193    
194                    if (!hasField(fieldName)) {
195                            throw new StructureFieldException(
196                                    "Unable to find field " + fieldName);
197                    }
198    
199                    Map<String, Map<String, String>> fieldsMap = getFieldsMap(locale, true);
200    
201                    Map<String, String> field = fieldsMap.get(fieldName);
202    
203                    return field.get(property);
204            }
205    
206            @Override
207            public boolean getFieldRepeatable(String fieldName)
208                    throws PortalException, SystemException {
209    
210                    return GetterUtil.getBoolean(getFieldProperty(fieldName, "repeatable"));
211            }
212    
213            @Override
214            public boolean getFieldRequired(String fieldName)
215                    throws PortalException, SystemException {
216    
217                    return GetterUtil.getBoolean(getFieldProperty(fieldName, "required"));
218            }
219    
220            @Override
221            public Map<String, String> getFields(
222                    String fieldName, String attributeName, String attributeValue) {
223    
224                    return getFields(
225                            fieldName, attributeName, attributeValue, getDefaultLanguageId());
226            }
227    
228            @Override
229            public Map<String, String> getFields(
230                    String fieldName, String attributeName, String attributeValue,
231                    String locale) {
232    
233                    try {
234                            if ((attributeName == null) || (attributeValue == null)) {
235                                    return null;
236                            }
237    
238                            Map<String, Map<String, String>> fieldsMap = getTransientFieldsMap(
239                                    locale);
240    
241                            for (Map<String, String> fields : fieldsMap.values()) {
242                                    String parentName = fields.get(
243                                            _getPrivateAttributeKey("parentName"));
244    
245                                    if (!fieldName.equals(parentName)) {
246                                            continue;
247                                    }
248    
249                                    if (attributeValue.equals(fields.get(attributeName))) {
250                                            return fields;
251                                    }
252                            }
253                    }
254                    catch (Exception e) {
255                            _log.error(e, e);
256                    }
257    
258                    return null;
259            }
260    
261            @Override
262            public Map<String, Map<String, String>> getFieldsMap()
263                    throws PortalException, SystemException {
264    
265                    return getFieldsMap(getDefaultLanguageId());
266            }
267    
268            @Override
269            public Map<String, Map<String, String>> getFieldsMap(
270                            boolean includeTransientFields)
271                    throws PortalException, SystemException {
272    
273                    return getFieldsMap(getDefaultLanguageId(), includeTransientFields);
274            }
275    
276            @Override
277            public Map<String, Map<String, String>> getFieldsMap(String locale)
278                    throws PortalException, SystemException {
279    
280                    return getFieldsMap(locale, false);
281            }
282    
283            @Override
284            public Map<String, Map<String, String>> getFieldsMap(
285                            String locale, boolean includeTransientFields)
286                    throws PortalException, SystemException {
287    
288                    _indexFieldsMap(locale);
289    
290                    Map<String, Map<String, Map<String, String>>> fieldsMap = null;
291    
292                    if (includeTransientFields) {
293                            fieldsMap = getLocalizedFieldsMap();
294                    }
295                    else {
296                            fieldsMap = getLocalizedPersistentFieldsMap();
297                    }
298    
299                    return fieldsMap.get(locale);
300            }
301    
302            @Override
303            public String getFieldTip(String fieldName, Locale locale)
304                    throws PortalException, SystemException {
305    
306                    return getFieldTip(fieldName, LocaleUtil.toLanguageId(locale));
307            }
308    
309            @Override
310            public String getFieldTip(String fieldName, String locale)
311                    throws PortalException, SystemException {
312    
313                    return GetterUtil.getString(
314                            getFieldProperty(fieldName, "tip", locale), fieldName);
315            }
316    
317            @Override
318            public String getFieldType(String fieldName)
319                    throws PortalException, SystemException {
320    
321                    return getFieldProperty(fieldName, "type");
322            }
323    
324            @Override
325            public Map<String, Map<String, Map<String, String>>>
326                    getLocalizedFieldsMap() {
327    
328                    if (_localizedFieldsMap == null) {
329                            _localizedFieldsMap =
330                                    new ConcurrentHashMap
331                                            <String, Map<String, Map<String, String>>>();
332                    }
333    
334                    return _localizedFieldsMap;
335            }
336    
337            @Override
338            public Map<String, Map<String, Map<String, String>>>
339                    getLocalizedPersistentFieldsMap() {
340    
341                    if (_localizedPersistentFieldsMap == null) {
342                            _localizedPersistentFieldsMap =
343                                    new ConcurrentHashMap
344                                            <String, Map<String, Map<String, String>>>();
345                    }
346    
347                    return _localizedPersistentFieldsMap;
348            }
349    
350            @Override
351            public Map<String, Map<String, Map<String, String>>>
352                    getLocalizedTransientFieldsMap() {
353    
354                    if (_localizedTransientFieldsMap == null) {
355                            _localizedTransientFieldsMap =
356                                    new ConcurrentHashMap
357                                            <String, Map<String, Map<String, String>>>();
358                    }
359    
360                    return _localizedTransientFieldsMap;
361            }
362    
363            @Override
364            public Map<String, Map<String, String>> getPersistentFieldsMap(
365                            String locale)
366                    throws PortalException, SystemException {
367    
368                    _indexFieldsMap(locale);
369    
370                    Map<String, Map<String, Map<String, String>>>
371                            localizedPersistentFieldsMap = getLocalizedPersistentFieldsMap();
372    
373                    Map<String, Map<String, String>> fieldsMap =
374                            localizedPersistentFieldsMap.get(locale);
375    
376                    return fieldsMap;
377            }
378    
379            @Override
380            public List<String> getRootFieldNames()
381                    throws PortalException, SystemException {
382    
383                    List<String> fieldNames = new ArrayList<String>();
384    
385                    Map<String, Map<String, String>> fieldsMap = getFieldsMap(true);
386    
387                    for (Map.Entry<String, Map<String, String>> entry :
388                                    fieldsMap.entrySet()) {
389    
390                            Map<String, String> field = entry.getValue();
391    
392                            String parentNameKey = _getPrivateAttributeKey("parentName");
393    
394                            if (!field.containsKey(parentNameKey)) {
395                                    fieldNames.add(entry.getKey());
396                            }
397                    }
398    
399                    return fieldNames;
400            }
401    
402            @Override
403            public List<DDMTemplate> getTemplates() throws SystemException {
404                    return DDMTemplateLocalServiceUtil.getTemplates(getStructureId());
405            }
406    
407            @Override
408            public Map<String, Map<String, String>> getTransientFieldsMap(String locale)
409                    throws PortalException, SystemException {
410    
411                    _indexFieldsMap(locale);
412    
413                    Map<String, Map<String, Map<String, String>>>
414                            localizedTransientFieldsMap = getLocalizedTransientFieldsMap();
415    
416                    Map<String, Map<String, String>> fieldsMap =
417                            localizedTransientFieldsMap.get(locale);
418    
419                    return fieldsMap;
420            }
421    
422            @Override
423            public String getUnambiguousName(
424                            List<DDMStructure> structures, long groupId, final Locale locale)
425                    throws PortalException, SystemException {
426    
427                    if (getGroupId() == groupId ) {
428                            return getName(locale);
429                    }
430    
431                    boolean hasAmbiguousName = ListUtil.exists(
432                            structures,
433                            new PredicateFilter<DDMStructure>() {
434    
435                                    @Override
436                                    public boolean filter(DDMStructure structure) {
437                                            String name = structure.getName(locale);
438    
439                                            if (name.equals(getName(locale)) &&
440                                                    (structure.getStructureId() != getStructureId())) {
441    
442                                                    return true;
443                                            }
444    
445                                            return false;
446                                    }
447    
448                            });
449    
450                    if (hasAmbiguousName) {
451                            Group group = GroupLocalServiceUtil.getGroup(getGroupId());
452    
453                            return group.getUnambiguousName(getName(locale), locale);
454                    }
455    
456                    return getName(locale);
457            }
458    
459            /**
460             * Returns the WebDAV URL to access the structure.
461             *
462             * @param  themeDisplay the theme display needed to build the URL. It can
463             *         set HTTPS access, the server name, the server port, the path
464             *         context, and the scope group.
465             * @param  webDAVToken the WebDAV token for the URL
466             * @return the WebDAV URL
467             */
468            @Override
469            public String getWebDavURL(ThemeDisplay themeDisplay, String webDAVToken) {
470                    StringBundler sb = new StringBundler(11);
471    
472                    boolean secure = false;
473    
474                    if (themeDisplay.isSecure() ||
475                            PropsValues.WEBDAV_SERVLET_HTTPS_REQUIRED) {
476    
477                            secure = true;
478                    }
479    
480                    String portalURL = PortalUtil.getPortalURL(
481                            themeDisplay.getServerName(), themeDisplay.getServerPort(), secure);
482    
483                    sb.append(portalURL);
484    
485                    sb.append(themeDisplay.getPathContext());
486                    sb.append(StringPool.SLASH);
487                    sb.append("webdav");
488    
489                    Group group = themeDisplay.getScopeGroup();
490    
491                    sb.append(group.getFriendlyURL());
492    
493                    sb.append(StringPool.SLASH);
494                    sb.append(webDAVToken);
495                    sb.append(StringPool.SLASH);
496                    sb.append("Structures");
497                    sb.append(StringPool.SLASH);
498                    sb.append(getStructureId());
499    
500                    return sb.toString();
501            }
502    
503            @Override
504            public boolean hasField(String fieldName)
505                    throws PortalException, SystemException {
506    
507                    Map<String, Map<String, String>> fieldsMap = getFieldsMap(true);
508    
509                    if (fieldsMap.containsKey(fieldName)) {
510                            return true;
511                    }
512    
513                    try {
514                            DDMStructure parentStructure =
515                                    DDMStructureLocalServiceUtil.getStructure(
516                                            getParentStructureId());
517    
518                            return parentStructure.hasField(fieldName);
519                    }
520                    catch (NoSuchStructureException nsse) {
521                            return false;
522                    }
523            }
524    
525            @Override
526            public boolean isFieldPrivate(String fieldName)
527                    throws PortalException, SystemException {
528    
529                    return GetterUtil.getBoolean(getFieldProperty(fieldName, "private"));
530            }
531    
532            @Override
533            public boolean isFieldRepeatable(String fieldName)
534                    throws PortalException, SystemException {
535    
536                    return GetterUtil.getBoolean(getFieldProperty(fieldName, "repeatable"));
537            }
538    
539            @Override
540            public boolean isFieldTransient(String fieldName)
541                    throws PortalException, SystemException {
542    
543                    if (!hasField(fieldName)) {
544                            throw new StructureFieldException();
545                    }
546    
547                    Map<String, Map<String, String>> transientFieldsMap =
548                            getTransientFieldsMap(getDefaultLanguageId());
549    
550                    return transientFieldsMap.containsKey(fieldName);
551            }
552    
553            @Override
554            public void prepareLocalizedFieldsForImport(Locale defaultImportLocale)
555                    throws LocaleException {
556    
557                    super.prepareLocalizedFieldsForImport(defaultImportLocale);
558    
559                    String defaultLanguageId = getDefaultLanguageId();
560    
561                    Locale siteDefaultLocale = LocaleUtil.getSiteDefault();
562    
563                    String name = getName(siteDefaultLocale);
564    
565                    if (Validator.isNull(name)) {
566                            setName(getName(defaultLanguageId), siteDefaultLocale);
567                    }
568                    else {
569                            setName(name, defaultImportLocale, siteDefaultLocale);
570                    }
571    
572                    String description = getDescription(siteDefaultLocale);
573    
574                    if (Validator.isNull(description)) {
575                            setDescription(
576                                    getDescription(defaultLanguageId), siteDefaultLocale);
577                    }
578                    else {
579                            setDescription(description, defaultImportLocale, siteDefaultLocale);
580                    }
581    
582                    Locale ddmStructureDefaultLocale = LocaleUtil.fromLanguageId(
583                            getDefaultLanguageId());
584    
585                    try {
586                            setXsd(
587                                    DDMXMLUtil.updateXMLDefaultLocale(
588                                            getXsd(), ddmStructureDefaultLocale, defaultImportLocale));
589                    }
590                    catch (Exception e) {
591                            throw new LocaleException(LocaleException.TYPE_EXPORT_IMPORT, e);
592                    }
593            }
594    
595            @Override
596            public void setDocument(Document document) {
597                    _document = document;
598            }
599    
600            @Override
601            public void setLocalizedFieldsMap(
602                    Map<String, Map<String, Map<String, String>>> localizedFieldsMap) {
603    
604                    _localizedFieldsMap = localizedFieldsMap;
605            }
606    
607            @Override
608            public void setLocalizedPersistentFieldsMap(
609                    Map<String, Map<String, Map<String, String>>>
610                            localizedPersistentFieldsMap) {
611    
612                    _localizedPersistentFieldsMap = localizedPersistentFieldsMap;
613            }
614    
615            @Override
616            public void setLocalizedTransientFieldsMap(
617                    Map<String, Map<String, Map<String, String>>>
618                            localizedTransientFieldsMap) {
619    
620                    _localizedTransientFieldsMap = localizedTransientFieldsMap;
621            }
622    
623            @Override
624            public void setXsd(String xsd) {
625                    super.setXsd(xsd);
626    
627                    _document = null;
628                    _localizedFieldsMap = null;
629                    _localizedPersistentFieldsMap = null;
630                    _localizedTransientFieldsMap = null;
631            }
632    
633            private Map<String, String> _getField(Element element, String locale) {
634                    Map<String, String> field = new HashMap<String, String>();
635    
636                    String[] availableLanguageIds = getAvailableLanguageIds();
637    
638                    if ((locale != null) &&
639                            !ArrayUtil.contains(availableLanguageIds, locale)) {
640    
641                            locale = getDefaultLanguageId();
642                    }
643    
644                    locale = HtmlUtil.escapeXPathAttribute(locale);
645    
646                    String xPathExpression =
647                            "meta-data[@locale=".concat(locale).concat("]");
648    
649                    XPath xPathSelector = SAXReaderUtil.createXPath(xPathExpression);
650    
651                    Node node = xPathSelector.selectSingleNode(element);
652    
653                    Element metaDataElement = (Element)node.asXPathResult(node.getParent());
654    
655                    if (metaDataElement != null) {
656                            List<Element> childMetaDataElements = metaDataElement.elements();
657    
658                            for (Element childMetaDataElement : childMetaDataElements) {
659                                    String name = childMetaDataElement.attributeValue("name");
660                                    String value = childMetaDataElement.getText();
661    
662                                    field.put(name, value);
663                            }
664                    }
665    
666                    for (Attribute attribute : element.attributes()) {
667                            field.put(attribute.getName(), attribute.getValue());
668                    }
669    
670                    Element parentElement = element.getParent();
671    
672                    if (parentElement != null) {
673                            String parentName = parentElement.attributeValue("name");
674    
675                            if (Validator.isNotNull(parentName)) {
676                                    field.put(_getPrivateAttributeKey("parentName"), parentName);
677                            }
678                    }
679    
680                    return field;
681            }
682    
683            private String _getPrivateAttributeKey(String attributeName) {
684                    return StringPool.UNDERLINE.concat(attributeName).concat(
685                            StringPool.UNDERLINE);
686            }
687    
688            private Map<String, String> _getPrivateField(String privateFieldName) {
689                    Map<String, String> privateField = new HashMap<String, String>();
690    
691                    String dataType = PropsUtil.get(
692                            PropsKeys.DYNAMIC_DATA_MAPPING_STRUCTURE_PRIVATE_FIELD_DATATYPE,
693                            new Filter(privateFieldName));
694    
695                    privateField.put("dataType", dataType);
696    
697                    privateField.put("name", privateFieldName);
698                    privateField.put("private", Boolean.TRUE.toString());
699    
700                    String repeatable = PropsUtil.get(
701                            PropsKeys.DYNAMIC_DATA_MAPPING_STRUCTURE_PRIVATE_FIELD_REPEATABLE,
702                            new Filter(privateFieldName));
703    
704                    privateField.put("repeatable", repeatable);
705    
706                    return privateField;
707            }
708    
709            private void _indexFieldsMap(String locale)
710                    throws PortalException, SystemException {
711    
712                    Map<String, Map<String, Map<String, String>>> localizedFieldsMap =
713                            getLocalizedFieldsMap();
714    
715                    Map<String, Map<String, String>> fieldsMap = localizedFieldsMap.get(
716                            locale);
717    
718                    Map<String, Map<String, Map<String, String>>>
719                            localizedPersistentFieldsMap = getLocalizedPersistentFieldsMap();
720    
721                    Map<String, Map<String, String>> persistentFieldsMap =
722                            localizedPersistentFieldsMap.get(locale);
723    
724                    Map<String, Map<String, Map<String, String>>>
725                            localizedTransientFieldsMap = getLocalizedTransientFieldsMap();
726    
727                    Map<String, Map<String, String>> transientFieldsMap =
728                            localizedTransientFieldsMap.get(locale);
729    
730                    if (fieldsMap != null) {
731                            return;
732                    }
733    
734                    fieldsMap = new LinkedHashMap<String, Map<String, String>>();
735                    persistentFieldsMap = new LinkedHashMap<String, Map<String, String>>();
736                    transientFieldsMap = new LinkedHashMap<String, Map<String, String>>();
737    
738                    if (getParentStructureId() > 0) {
739                            DDMStructure parentStructure =
740                                    DDMStructureLocalServiceUtil.getStructure(
741                                            getParentStructureId());
742    
743                            fieldsMap.putAll(parentStructure.getFieldsMap(locale, true));
744                            persistentFieldsMap.putAll(
745                                    parentStructure.getPersistentFieldsMap(locale));
746                            transientFieldsMap.putAll(
747                                    parentStructure.getTransientFieldsMap(locale));
748                    }
749    
750                    XPath xPathSelector = SAXReaderUtil.createXPath("//dynamic-element");
751    
752                    List<Node> nodes = xPathSelector.selectNodes(getDocument());
753    
754                    for (Node node : nodes) {
755                            Element element = (Element)node;
756    
757                            String name = element.attributeValue("name");
758    
759                            fieldsMap.put(name, _getField(element, locale));
760    
761                            if (Validator.isNotNull(element.attributeValue("dataType"))) {
762                                    persistentFieldsMap.put(name, _getField(element, locale));
763                            }
764                            else {
765                                    transientFieldsMap.put(name, _getField(element, locale));
766                            }
767                    }
768    
769                    String[] privateFieldNames =
770                            PropsValues.DYNAMIC_DATA_MAPPING_STRUCTURE_PRIVATE_FIELD_NAMES;
771    
772                    for (String privateFieldName : privateFieldNames) {
773                            Map<String, String> privateField = _getPrivateField(
774                                    privateFieldName);
775    
776                            fieldsMap.put(privateFieldName, privateField);
777                            persistentFieldsMap.put(privateFieldName, privateField);
778                    }
779    
780                    localizedFieldsMap.put(locale, fieldsMap);
781                    localizedPersistentFieldsMap.put(locale, persistentFieldsMap);
782                    localizedTransientFieldsMap.put(locale, transientFieldsMap);
783            }
784    
785            private String _mergeXsds(String xsd1, String xsd2) throws SystemException {
786                    try {
787                            Document document1 = SAXReaderUtil.read(xsd1);
788                            Document document2 = SAXReaderUtil.read(xsd2);
789    
790                            Element rootElement1 = document1.getRootElement();
791                            Element rootElement2 = document2.getRootElement();
792    
793                            for (Element element : rootElement1.elements()) {
794                                    rootElement1.remove(element);
795    
796                                    rootElement2.add(element);
797                            }
798    
799                            return rootElement2.formattedString();
800                    }
801                    catch (Exception e) {
802                            throw new SystemException(e);
803                    }
804            }
805    
806            private static Log _log = LogFactoryUtil.getLog(DDMStructureImpl.class);
807    
808            @CacheField
809            private Document _document;
810    
811            @CacheField
812            private Map<String, Map<String, Map<String, String>>> _localizedFieldsMap;
813    
814            @CacheField
815            private Map<String, Map<String, Map<String, String>>>
816                    _localizedPersistentFieldsMap;
817    
818            @CacheField
819            private Map<String, Map<String, Map<String, String>>>
820                    _localizedTransientFieldsMap;
821    
822    }