    001// Copyright 2006, 2008, 2009, 2010, 2011 The Apache Software Foundation
    002//
    003// Licensed under the Apache License, Version 2.0 (the "License");
    004// you may not use this file except in compliance with the License.
    005// You may obtain a copy of the License at
    006//
    007// http://www.apache.org/licenses/LICENSE-2.0
    008//
    009// Unless required by applicable law or agreed to in writing, software
    010// distributed under the License is distributed on an "AS IS" BASIS,
    011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012// See the License for the specific language governing permissions and
    013// limitations under the License.
    014
    015package org.apache.tapestry5.internal.model;
    016
    017import java.util.Collections;
    018import java.util.List;
    019import java.util.Map;
    020
    021import org.apache.tapestry5.commons.Location;
    022import org.apache.tapestry5.commons.util.CollectionFactory;
    023import org.apache.tapestry5.ioc.BaseLocatable;
    024import org.apache.tapestry5.ioc.internal.util.InternalUtils;
    025import org.apache.tapestry5.model.MutableEmbeddedComponentModel;
    026
    027public class MutableEmbeddedComponentModelImpl extends BaseLocatable implements MutableEmbeddedComponentModel
    028{
    029    private final String id;
    030
    031    private final String componentType;
    032
    033    private final String componentClassName;
    034
    035    private final String declaredClass;
    036
    037    private final boolean inheritInformalParameters;
    038
    039    private Map<String, String> parameters;
    040
    041    private List<String> publishedParameters = Collections.emptyList();
    042
    043    /**
    044     * List of mixin class names.
    045     */
    046    private List<String> mixinClassNames;
    047
    048    private Map<String, String[]> mixinConstraints;
    049
    050    public MutableEmbeddedComponentModelImpl(String id, String componentType, String componentClassName,
    051            String declaredClass, boolean inheritInformalParameters, Location location)
    052    {
    053        super(location);
    054
    055        this.id = id;
    056        this.componentType = componentType;
    057        this.componentClassName = componentClassName;
    058        this.inheritInformalParameters = inheritInformalParameters;
    059        this.declaredClass = declaredClass;
    060    }
    061
    062    public String getComponentClassName()
    063    {
    064        return componentClassName;
    065    }
    066
    067    @Override
    068    public String toString()
    069    {
    070        return String.format("EmbeddedComponentModel[id=%s type=%s class=%s inheritInformals=%s]", id, componentType,
    071                componentClassName, inheritInformalParameters);
    072    }
    073
    074    public void addParameter(String name, String value)
    075    {
    076        if (parameters == null)
    077            parameters = CollectionFactory.newMap();
    078        else if (parameters.containsKey(name))
    079            throw new IllegalArgumentException(String.format("A value for parameter '%s' of embedded component %s (of component class %s) has already been provided.", name, id, declaredClass));
    080
    081        parameters.put(name, value);
    082    }
    083
    084    public String getId()
    085    {
    086        return id;
    087    }
    088
    089    public String getComponentType()
    090    {
    091        return componentType;
    092    }
    093
    094    public List<String> getParameterNames()
    095    {
    096        return InternalUtils.sortedKeys(parameters);
    097    }
    098
    099    public String getParameterValue(String parameterName)
    100    {
    101        return InternalUtils.get(parameters, parameterName);
    102    }
    103
    104    public List<String> getMixinClassNames()
    105    {
    106        if (mixinClassNames == null)
    107            return Collections.emptyList();
    108
    109        return Collections.unmodifiableList(mixinClassNames);
    110    }
    111
    112    public void addMixin(String mixinClassName, String... constraints)
    113    {
    114        if (mixinClassNames == null)
    115        {
    116            mixinClassNames = CollectionFactory.newList();
    117            mixinConstraints = CollectionFactory.newCaseInsensitiveMap();
    118        }
    119        else
    120        {
    121            if (mixinClassNames.contains(mixinClassName))
    122                throw new IllegalArgumentException(String.format("Mixin %s (for component %s) has already been defined.", mixinClassName, id));
    123        }
    124
    125        mixinClassNames.add(mixinClassName);
    126        mixinConstraints.put(mixinClassName, constraints);
    127    }
    128
    129    public boolean getInheritInformalParameters()
    130    {
    131        return inheritInformalParameters;
    132    }
    133
    134    public void setPublishedParameters(List<String> parameterNames)
    135    {
    136        assert parameterNames != null;
    137        publishedParameters = parameterNames;
    138    }
    139
    140    public List<String> getPublishedParameters()
    141    {
    142        return publishedParameters;
    143    }
    144
    145    public String[] getConstraintsForMixin(String mixinClassName)
    146    {
    147        return InternalUtils.get(mixinConstraints, mixinClassName);
    148    }
    149}