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.w3c.dom.Element;
024import org.w3c.dom.Node;
025
026import org.ametys.core.util.dom.AbstractWrappingAmetysElement;
027import org.ametys.core.util.dom.AmetysAttribute;
028import org.ametys.core.util.dom.AmetysText;
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 MetadataElement extends AbstractWrappingAmetysElement<String>
036{
037    CompositeMetadata _metadataHolder;
038    private String _defaultValue;
039    
040    /**
041     * Constructor.
042     * @param metadataName the name of underlying metadata
043     * @param metadataHolder the parent {@link CompositeMetadata}
044     */
045    public MetadataElement(String metadataName, CompositeMetadata metadataHolder)
046    {
047        this(metadataName, metadataHolder, null, "");
048    }
049    
050    /**
051     * Constructor.
052     * @param metadataName the name of underlying metadata
053     * @param metadataHolder the parent {@link CompositeMetadata}
054     * @param defaultValue the default value
055     */
056    public MetadataElement(String metadataName, CompositeMetadata metadataHolder, String defaultValue)
057    {
058        this(metadataName, metadataHolder, null, defaultValue);
059    }
060    
061    /**
062     * Constructor.
063     * @param metadataName the name of underlying metadata
064     * @param metadataHolder the parent {@link CompositeMetadata}
065     * @param parent the parent {@link Element}.
066     */
067    public MetadataElement(String metadataName, CompositeMetadata metadataHolder, CompositeMetadataElement parent)
068    {
069        this(metadataName, metadataHolder, parent, "");
070    }
071
072    /**
073     * Constructor.
074     * @param metadataName the name of underlying metadata
075     * @param metadataHolder the parent {@link CompositeMetadata}
076     * @param parent the parent {@link Element}.
077     * @param defaultValue the default value
078     */
079    public MetadataElement(String metadataName, CompositeMetadata metadataHolder, CompositeMetadataElement parent, String defaultValue)
080    {
081        super(metadataName, parent);
082        _metadataHolder = metadataHolder;
083        _defaultValue = defaultValue;
084    }
085    
086    @Override
087    public String getTagName()
088    {
089        return _object;
090    }
091    
092    @Override
093    protected Map<String, AmetysAttribute> _lookupAttributes()
094    {
095        Map<String, AmetysAttribute> result = new HashMap<>();
096        MetadataType type = _metadataHolder.getType(_object);
097        result.put("type", new AmetysAttribute("type", "type", null, type.toString(), this));
098        return result;
099    }
100    
101    @Override
102    public boolean hasChildNodes()
103    {
104        return _object.length() > 0;
105    }
106    
107    @Override
108    public Node getFirstChild()
109    {
110        return new AmetysText(_metadataHolder.getString(_object, _defaultValue), this);
111    }
112    
113    @Override
114    public Node getNextSibling()
115    {
116        if (_parent == null)
117        {
118            return null;
119        }
120        
121        boolean isNext = false;
122        String nextSibling = null;
123        int i = 0;
124        
125        String[] brothers = _metadataHolder.getMetadataNames();
126        while (nextSibling == null && i < brothers.length)
127        {
128            String brother = brothers[i++];
129            
130            if (isNext)
131            {
132                nextSibling = brother;
133            }
134            else if (_object.equals(brother))
135            {
136                isNext = true;
137            }
138        }
139        
140        if (nextSibling == null)
141        {
142            return null;
143        }
144        
145        MetadataType type = _metadataHolder.getType(nextSibling);
146        switch (type)
147        {
148            case COMPOSITE:
149                return new CompositeMetadataElement(_metadataHolder.getCompositeMetadata(nextSibling), nextSibling, (CompositeMetadataElement) getParentNode());
150            case USER:
151                return new UserMetadataElement(_metadataHolder.getCompositeMetadata(nextSibling), nextSibling, (CompositeMetadataElement) getParentNode());
152            case MULTILINGUAL_STRING:
153                return new MultilingualStringElement(_metadataHolder.getMultilingualString(nextSibling), nextSibling, (CompositeMetadataElement) getParentNode());
154            default:
155                return new MetadataElement(nextSibling, _metadataHolder, (CompositeMetadataElement) getParentNode());
156        }
157    }
158}