001/*
002 *  Copyright 2011 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.io.File;
020import java.util.HashMap;
021import java.util.Map;
022
023import org.apache.commons.lang.StringUtils;
024import org.w3c.dom.Element;
025import org.w3c.dom.Node;
026
027import org.ametys.core.util.dom.AbstractWrappingAmetysElement;
028import org.ametys.core.util.dom.AmetysAttribute;
029import org.ametys.plugins.repository.metadata.CompositeMetadata;
030import org.ametys.plugins.repository.metadata.CompositeMetadata.MetadataType;
031
032/**
033 * DOM layer on top if a {@link File} hierarchy.
034 */
035public class CompositeMetadataElement extends AbstractWrappingAmetysElement<CompositeMetadata>
036{
037    String _name;
038    
039    /**
040     * Constructor.
041     * @param metadata the underlying {@link CompositeMetadata}.
042     * @param name the name of underlying {@link CompositeMetadata}
043     */
044    public CompositeMetadataElement(CompositeMetadata metadata, String name)
045    {
046        this(metadata, name, null);
047    }
048
049    /**
050     * Constructor.
051     * @param metadata the underlying {@link CompositeMetadata}.
052     * @param name the name of underlying {@link CompositeMetadata}
053     * @param parent the parent {@link Element}.
054     */
055    public CompositeMetadataElement(CompositeMetadata metadata, String name, CompositeMetadataElement parent)
056    {
057        super(metadata, parent);
058        _name = name;
059    }
060    
061    @Override
062    public String getTagName()
063    {
064        char c = _name.charAt(0);
065        if (c >= '0' && c <= '9')
066        {
067            String hex = Integer.toHexString(c);
068            return "_x" + StringUtils.leftPad(hex, 4, '0') + "_" + _name.substring(1);
069        }
070        else
071        {
072            return _name;
073        }
074    }
075    
076    @Override
077    protected Map<String, AmetysAttribute> _lookupAttributes()
078    {
079        Map<String, AmetysAttribute> result = new HashMap<>();
080        result.put("name", new AmetysAttribute("name", "name", null, _name, this));
081        result.put("type", new AmetysAttribute("type", "type", null, MetadataType.COMPOSITE.toString(), this));
082        return result;
083    }
084    
085    @Override
086    public boolean hasChildNodes()
087    {
088        String[] childNames = _object.getMetadataNames();
089        return childNames != null ? childNames.length > 0 : false;
090    }
091    
092    @Override
093    public Node getFirstChild()
094    {
095        String[] childNames = _object.getMetadataNames();
096        
097        if (childNames != null && childNames.length > 0)
098        {
099            if (_object.getType(childNames[0]).equals(MetadataType.COMPOSITE))
100            {
101                return new CompositeMetadataElement(_object.getCompositeMetadata(childNames[0]), childNames[0], this);
102            }
103            else if (_object.getType(childNames[0]).equals(MetadataType.USER))
104            {
105                return new UserMetadataElement(_object.getCompositeMetadata(childNames[0]), childNames[0], this);
106            }
107            else
108            {
109                return new MetadataElement(childNames[0], _object, this);
110            }
111        }
112        
113        return null;
114    }
115    
116    @Override
117    public Node getNextSibling()
118    {
119        if (_parent == null)
120        {
121            return null;
122        }
123        
124        CompositeMetadataElement parentElement = (CompositeMetadataElement) _parent;
125        
126        CompositeMetadata parent = parentElement.getWrappedObject();
127        
128        String[] children = parent.getMetadataNames();
129        
130        boolean isNext = false;
131        String nextSibling = null;
132        int i = 0;
133        
134        while (nextSibling == null && i < children.length)
135        {
136            String child = children[i++];
137            
138            if (isNext)
139            {
140                nextSibling = child;
141            }
142            else if (_name.equals(child))
143            {
144                isNext = true;
145            }
146        }
147        
148        if (nextSibling != null)
149        {
150            MetadataType type = parent.getType(nextSibling);
151            switch (type)
152            {
153                case COMPOSITE:
154                    return new CompositeMetadataElement(parent.getCompositeMetadata(nextSibling), nextSibling, parentElement);
155                case USER:
156                    return new UserMetadataElement(parent.getCompositeMetadata(nextSibling), nextSibling, parentElement);
157                case MULTILINGUAL_STRING:
158                    return new MultilingualStringElement(parent.getMultilingualString(nextSibling), nextSibling, parentElement);
159                default:
160                    return new MetadataElement(nextSibling, parent);
161            }
162        }
163        
164        return null;
165    }
166}