001/*
002 *  Copyright 2020 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 */
016package org.ametys.runtime.model;
017
018import java.util.ArrayList;
019import java.util.List;
020import java.util.Objects;
021
022import org.ametys.runtime.model.exception.BadItemTypeException;
023
024/**
025 * View element that can access to other view items
026 */
027public class ViewElementAccessor extends ViewElement implements ViewItemAccessor
028{
029    private List<ViewItem> _viewItems = new ArrayList<>();
030
031    public List<ViewItem> getViewItems()
032    {
033        return _viewItems;
034    }
035
036    public void addViewItem(ViewItem item)
037    {
038        _viewItems.add(item);
039        item.setParent(this);
040    }
041
042    public void insertViewItem(ViewItem item, int index)
043    {
044        if (index >= 0 && index <= _viewItems.size())
045        {
046            _viewItems.add(index, item);
047            item.setParent(this);
048        }
049        else
050        {
051            throw new IllegalArgumentException("Unable to insert an item at index " + index + ". This group contains " + _viewItems.size() + " items.");
052        }
053    }
054    
055    public boolean removeViewItem(ViewItem item)
056    {
057        return _viewItems.remove(item);
058    }
059    
060    public void clear()
061    {
062        _viewItems.clear();
063    }
064    
065    /**
066     * Creates a {@link ViewElementAccessor} with the items of the given {@link ModelItemAccessor}
067     * @param modelItemAccessor the model item accessor
068     * @return the created {@link ViewElementAccessor}
069     * @throws IllegalArgumentException if the model item accessor is <code>null</code>
070     */
071    public static ViewElementAccessor of(ModelItemAccessor modelItemAccessor) throws IllegalArgumentException
072    {
073        if (modelItemAccessor == null)
074        {
075            throw new IllegalArgumentException("Unable to create the view from a null model");
076        }
077        else
078        {
079            return ViewHelper.createViewItemAccessor(List.of(modelItemAccessor));
080        }
081    }
082    
083    /**
084     * Creates a {@link ViewElementAccessor} with the given items
085     * @param modelItemAccessor the model item accessing the items definitions
086     * @param itemPaths the paths of the items to put in the view item
087     * @return the created {@link ViewElementAccessor}
088     * @throws IllegalArgumentException if the model item accessor is <code>null</code> or if an item path is <code>null</code>, empty, or is not defined in the given model items
089     * @throws BadItemTypeException if a segment in a path (but not the last) does not represent a group item
090     */
091    public static ViewElementAccessor of(ModelItemAccessor modelItemAccessor, String... itemPaths) throws IllegalArgumentException, BadItemTypeException
092    {
093        if (modelItemAccessor == null)
094        {
095            throw new IllegalArgumentException("Unable to create the view from a null model");
096        }
097        else
098        {
099            return ViewHelper.createViewItemAccessor(List.of(modelItemAccessor), itemPaths);
100        }
101    }
102    
103    @Override
104    public void copyTo(ViewItem item, ViewItemAccessor referenceViewItemAccessor, String itemPath)
105    {
106        super.copyTo(item, referenceViewItemAccessor, itemPath);
107        
108        assert item instanceof ViewElementAccessor;
109        ViewHelper.addViewAccessorItems((ViewElementAccessor) item, this, referenceViewItemAccessor, itemPath);
110    }
111    
112    @Override
113    public ViewElementAccessor createInstance()
114    {
115        return new ViewElementAccessor();
116    }
117
118    @Override
119    public int hashCode()
120    {
121        final int prime = 31;
122        int result = super.hashCode();
123        result = prime * result + Objects.hash(_viewItems);
124        return result;
125    }
126
127    @Override
128    public boolean equals(Object obj)
129    {
130        if (this == obj)
131        {
132            return true;
133        }
134        if (!super.equals(obj))
135        {
136            return false;
137        }
138        if (getClass() != obj.getClass())
139        {
140            return false;
141        }
142        ViewElementAccessor other = (ViewElementAccessor) obj;
143        return Objects.equals(_viewItems, other._viewItems);
144    }
145    
146    @Override
147    public String toString()
148    {
149        return super.toString() + ": " + _viewItems.toString();
150    }
151}