001/*
002 *  Copyright 2017 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016
017package org.ametys.plugins.repository.dom;
018
019import java.util.HashMap;
020import java.util.Iterator;
021import java.util.Locale;
022import java.util.Map;
023
024import org.apache.commons.lang.StringUtils;
025import org.w3c.dom.Element;
026import org.w3c.dom.Node;
027
028import org.ametys.core.util.dom.AbstractWrappingAmetysElement;
029import org.ametys.core.util.dom.AmetysAttribute;
030import org.ametys.plugins.repository.metadata.CompositeMetadata;
031import org.ametys.plugins.repository.metadata.CompositeMetadata.MetadataType;
032import org.ametys.plugins.repository.metadata.MultilingualString;
033
034/**
035 * DOM layer for a {@link MultilingualString} metadata
036 */
037public class MultilingualStringElement extends AbstractWrappingAmetysElement<MultilingualString>
038{
039    String _name;
040    
041    /**
042     * Constructor.
043     * @param multilingualString the underlying {@link MultilingualString}.
044     * @param name the name of underlying {@link MultilingualString}
045     */
046    public MultilingualStringElement(MultilingualString multilingualString, String name)
047    {
048        this(multilingualString, name, null);
049    }
050
051    /**
052     * Constructor.
053     * @param multilingualString the underlying {@link MultilingualString}.
054     * @param name the name of underlying {@link MultilingualString}
055     * @param parent the parent {@link Element}.
056     */
057    public MultilingualStringElement(MultilingualString multilingualString, String name, CompositeMetadataElement parent)
058    {
059        super(multilingualString, parent);
060        _name = name;
061    }
062    
063    @Override
064    public String getTagName()
065    {
066        char c = _name.charAt(0);
067        if (c >= '0' && c <= '9')
068        {
069            String hex = Integer.toHexString(c);
070            return "_x" + StringUtils.leftPad(hex, 4, '0') + "_" + _name.substring(1);
071        }
072        else
073        {
074            return _name;
075        }
076    }
077    
078    @Override
079    protected Map<String, AmetysAttribute> _lookupAttributes()
080    {
081        Map<String, AmetysAttribute> result = new HashMap<>();
082        result.put("name", new AmetysAttribute("name", "name", null, _name, this));
083        result.put("type", new AmetysAttribute("type", "type", null, MetadataType.MULTILINGUAL_STRING.toString(), this));
084        return result;
085    }
086    
087    @Override
088    public boolean hasChildNodes()
089    {
090        return _object.getLocales().size() > 0;
091    }
092    
093    @Override
094    public Node getFirstChild()
095    {
096        Iterator<Locale> locales = _object.getLocales().iterator();
097        
098        if (locales.hasNext())
099        {
100            Locale first = locales.next();
101            return new LocaleStringElement(first, _object, this);
102        }
103        
104        return null;
105    }
106    
107    @Override
108    public Node getNextSibling()
109    {
110        if (_parent == null)
111        {
112            return null;
113        }
114        
115        CompositeMetadataElement parentElement = (CompositeMetadataElement) _parent;
116        
117        CompositeMetadata parent = parentElement.getWrappedObject();
118        
119        String[] children = parent.getMetadataNames();
120        
121        boolean isNext = false;
122        String nextSibling = null;
123        int i = 0;
124        
125        while (nextSibling == null && i < children.length)
126        {
127            String child = children[i++];
128            
129            if (isNext)
130            {
131                nextSibling = child;
132            }
133            else if (_name.equals(child))
134            {
135                isNext = true;
136            }
137        }
138        
139        if (nextSibling != null)
140        {
141            MetadataType type = parent.getType(nextSibling);
142            switch (type)
143            {
144                case COMPOSITE:
145                    return new CompositeMetadataElement(parent.getCompositeMetadata(nextSibling), nextSibling, parentElement);
146                case USER:
147                    return new UserMetadataElement(parent.getCompositeMetadata(nextSibling), nextSibling, parentElement);
148                case MULTILINGUAL_STRING:
149                    return new MultilingualStringElement(parent.getMultilingualString(nextSibling), nextSibling, parentElement);
150                default:
151                    return new MetadataElement(nextSibling, parent);
152            }
153        }
154        
155        return null;
156    }
157}