001/*
002 *  Copyright 2019 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.cms.data.type.impl;
017
018import java.io.IOException;
019import java.util.Collection;
020import java.util.Optional;
021
022import org.apache.cocoon.xml.AttributesImpl;
023import org.apache.cocoon.xml.XMLUtils;
024import org.xml.sax.ContentHandler;
025import org.xml.sax.SAXException;
026
027import org.ametys.core.model.type.AbstractModelItemType;
028import org.ametys.plugins.repository.RepositoryConstants;
029import org.ametys.plugins.repository.data.UnknownDataException;
030import org.ametys.plugins.repository.data.holder.group.impl.ModelAwareComposite;
031import org.ametys.plugins.repository.data.holder.group.impl.ModelLessComposite;
032import org.ametys.plugins.repository.data.holder.impl.DataHolderHelper;
033import org.ametys.plugins.repository.data.repositorydata.RepositoryData;
034import org.ametys.plugins.repository.data.type.RepositoryModelItemGroupType;
035import org.ametys.plugins.repository.model.CompositeDefinition;
036import org.ametys.runtime.model.ModelItemContainer;
037import org.ametys.runtime.model.ModelViewItemGroup;
038import org.ametys.runtime.model.ViewItem;
039import org.ametys.runtime.model.ViewItemAccessor;
040import org.ametys.runtime.model.type.DataContext;
041
042/**
043 * Class for composite type
044 */
045public class CompositeRepositoryModelItemType extends AbstractModelItemType implements RepositoryModelItemGroupType
046{
047    public void valueToSAXForEdition(ContentHandler contentHandler, String tagName, Object value, Optional<ViewItem> viewItem, DataContext context) throws SAXException, IOException
048    {
049        _valueToSAX(contentHandler, tagName, value, viewItem, context, true);
050    }
051    
052    public void valueToSAX(ContentHandler contentHandler, String tagName, Object value, Optional<ViewItem> viewItem, DataContext context) throws SAXException, IOException
053    {
054        _valueToSAX(contentHandler, tagName, value, viewItem, context, false);
055    }
056    
057    private void _valueToSAX(ContentHandler contentHandler, String tagName, Object value, Optional<ViewItem> viewItem, DataContext context, boolean isEdition) throws SAXException, IOException
058    {
059        AttributesImpl attributes = _getContextAttributes(context, true);
060        
061        if (value == null)
062        {
063            XMLUtils.createElement(contentHandler, tagName, attributes);
064        }
065        else if (value instanceof ModelAwareComposite)
066        {
067            ModelAwareComposite composite = (ModelAwareComposite) value;
068            
069            if (viewItem.isPresent())
070            {
071                ViewItem compositeViewItem = viewItem.get();
072                assert compositeViewItem instanceof ViewItemAccessor;
073                
074                XMLUtils.startElement(contentHandler, tagName, attributes);
075                DataHolderHelper.dataToSAX(composite, contentHandler, (ViewItemAccessor) compositeViewItem, context, isEdition);
076                XMLUtils.endElement(contentHandler, tagName);
077            }
078            else
079            {
080                XMLUtils.startElement(contentHandler, tagName, attributes);
081                
082                CompositeDefinition compositeDefinition = _getCompositeDefinition(composite);
083                ModelViewItemGroup viewItemAccessor = ModelViewItemGroup.of(compositeDefinition);
084                DataHolderHelper.dataToSAX(composite, contentHandler, viewItemAccessor, context, isEdition);
085                
086                XMLUtils.endElement(contentHandler, tagName);
087            }
088        }
089        else if (value instanceof ModelLessComposite)
090        {
091            ModelLessComposite composite = (ModelLessComposite) value;
092            
093            XMLUtils.startElement(contentHandler, tagName, attributes);
094            DataHolderHelper.dataToSAX(composite, contentHandler, context);
095            XMLUtils.endElement(contentHandler, tagName);
096        }
097        else
098        {
099            throw new IllegalArgumentException("Try to sax the non composite value '" + value + "' in tag name '" + tagName + "'");
100        }
101    }
102    
103    private CompositeDefinition _getCompositeDefinition(ModelAwareComposite composite)
104    {
105        Collection<? extends ModelItemContainer> modelItemContainers = composite.getModel();
106        assert modelItemContainers.size() == 1;
107        
108        ModelItemContainer modelItemContainer = modelItemContainers.iterator().next();
109        assert modelItemContainer instanceof CompositeDefinition;
110        
111        return (CompositeDefinition) modelItemContainer;
112    }
113    
114    public boolean isCompatible(RepositoryData parentData, String name) throws UnknownDataException
115    {
116        // TODO NEWATTRIBUTEAPI: The second part of the test is here just to be compatible with the old compositMetadata type. When all composites are migrated, remove this part of the test
117        return RepositoryModelItemGroupType.super.isCompatible(parentData, name) || RepositoryConstants.COMPOSITE_METADTA_NODETYPE.equals(parentData.getType(name));
118    }
119    
120    public String getRepositoryDataType()
121    {
122        return RepositoryConstants.COMPOSITE_NODETYPE;
123    }
124}