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}