Coverage Report - org.apache.tapestry5.internal.model.MutableComponentModelImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
MutableComponentModelImpl
99%
93/94
100%
62/62
0
 
 1  
 // Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
 2  
 //
 3  
 // Licensed under the Apache License, Version 2.0 (the "License");
 4  
 // you may not use this file except in compliance with the License.
 5  
 // You may obtain a copy of the License at
 6  
 //
 7  
 //     http://www.apache.org/licenses/LICENSE-2.0
 8  
 //
 9  
 // Unless required by applicable law or agreed to in writing, software
 10  
 // distributed under the License is distributed on an "AS IS" BASIS,
 11  
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
 // See the License for the specific language governing permissions and
 13  
 // limitations under the License.
 14  
 
 15  
 package org.apache.tapestry5.internal.model;
 16  
 
 17  
 import org.apache.tapestry5.ioc.Location;
 18  
 import org.apache.tapestry5.ioc.Resource;
 19  
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 20  
 import org.apache.tapestry5.ioc.internal.util.Defense;
 21  
 import org.apache.tapestry5.ioc.internal.util.IdAllocator;
 22  
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 23  
 import org.apache.tapestry5.model.*;
 24  
 import org.slf4j.Logger;
 25  
 
 26  
 import java.util.Collections;
 27  
 import java.util.List;
 28  
 import java.util.Map;
 29  
 import java.util.Set;
 30  
 
 31  
 /**
 32  
  * Internal implementation of {@link org.apache.tapestry5.model.MutableComponentModel}.
 33  
  */
 34  
 public final class MutableComponentModelImpl implements MutableComponentModel
 35  
 {
 36  
     private final ComponentModel parentModel;
 37  
 
 38  
     private final Resource baseResource;
 39  
 
 40  
     private final String componentClassName;
 41  
 
 42  968
     private final IdAllocator persistentFieldNameAllocator = new IdAllocator();
 43  
 
 44  
     private final Logger logger;
 45  
 
 46  
     private Map<String, ParameterModel> parameters;
 47  
 
 48  
     private Map<String, EmbeddedComponentModel> embeddedComponents;
 49  
 
 50  
     /**
 51  
      * Maps from field name to strategy.
 52  
      */
 53  
     private Map<String, String> persistentFields;
 54  
 
 55  
     private List<String> mixinClassNames;
 56  
 
 57  
     private boolean informalParametersSupported;
 58  
 
 59  
     private boolean mixinAfter;
 60  
 
 61  
     private Map<String, String> metaData;
 62  
 
 63  
     private Set<Class> handledRenderPhases;
 64  
 
 65  
     private Map<String, Boolean> handledEvents;
 66  
 
 67  
     public MutableComponentModelImpl(String componentClassName, Logger logger, Resource baseResource,
 68  
                                      ComponentModel parentModel)
 69  968
     {
 70  968
         this.componentClassName = componentClassName;
 71  968
         this.logger = logger;
 72  968
         this.baseResource = baseResource;
 73  968
         this.parentModel = parentModel;
 74  
 
 75  
         // Pre-allocate names from the parent, to avoid name collisions.
 76  
 
 77  968
         if (this.parentModel != null)
 78  
         {
 79  164
             for (String name : this.parentModel.getPersistentFieldNames())
 80  
             {
 81  8
                 persistentFieldNameAllocator.allocateId(name);
 82  
             }
 83  
         }
 84  968
     }
 85  
 
 86  
     @Override
 87  
     public String toString()
 88  
     {
 89  0
         return String.format("ComponentModel[%s]", componentClassName);
 90  
     }
 91  
 
 92  
     public Logger getLogger()
 93  
     {
 94  5718
         return logger;
 95  
     }
 96  
 
 97  
     public Resource getBaseResource()
 98  
     {
 99  1496
         return baseResource;
 100  
     }
 101  
 
 102  
     public String getComponentClassName()
 103  
     {
 104  12429
         return componentClassName;
 105  
     }
 106  
 
 107  
     public void addParameter(String name, boolean required, boolean allowNull, String defaultBindingPrefix)
 108  
     {
 109  902
         Defense.notBlank(name, "name");
 110  902
         Defense.notBlank(defaultBindingPrefix, "defaultBindingPrefix");
 111  
 
 112  
         // TODO: Check for conflict with base model
 113  
 
 114  902
         if (parameters == null)
 115  254
             parameters = CollectionFactory.newCaseInsensitiveMap();
 116  
 
 117  902
         if (parameters.containsKey(name))
 118  2
             throw new IllegalArgumentException(ModelMessages.duplicateParameter(name, componentClassName));
 119  
 
 120  900
         parameters.put(name, new ParameterModelImpl(name, required, allowNull, defaultBindingPrefix));
 121  900
     }
 122  
 
 123  
     public ParameterModel getParameterModel(String parameterName)
 124  
     {
 125  38199
         ParameterModel result = InternalUtils.get(parameters, parameterName.toLowerCase());
 126  
 
 127  38199
         if (result == null && parentModel != null) result = parentModel.getParameterModel(parameterName);
 128  
 
 129  38199
         return result;
 130  
     }
 131  
 
 132  
     public List<String> getParameterNames()
 133  
     {
 134  8604
         List<String> names = CollectionFactory.newList();
 135  
 
 136  8604
         if (parameters != null) names.addAll(parameters.keySet());
 137  
 
 138  8604
         if (parentModel != null) names.addAll(parentModel.getParameterNames());
 139  
 
 140  8604
         Collections.sort(names);
 141  
 
 142  8604
         return names;
 143  
     }
 144  
 
 145  
     public List<String> getDeclaredParameterNames()
 146  
     {
 147  6
         return InternalUtils.sortedKeys(parameters);
 148  
     }
 149  
 
 150  
     public MutableEmbeddedComponentModel addEmbeddedComponent(String id, String type, String componentClassName,
 151  
                                                               boolean inheritInformalParameters, Location location)
 152  
     {
 153  
         // TODO: Parent compent model? Or would we simply override the parent?
 154  
 
 155  190
         if (embeddedComponents == null) embeddedComponents = CollectionFactory.newCaseInsensitiveMap();
 156  102
         else if (embeddedComponents.containsKey(id))
 157  4
             throw new IllegalArgumentException(ModelMessages.duplicateComponentId(id, this.componentClassName));
 158  
 
 159  186
         MutableEmbeddedComponentModel embedded = new MutableEmbeddedComponentModelImpl(id, type, componentClassName,
 160  
                                                                                        this.componentClassName,
 161  
                                                                                        inheritInformalParameters,
 162  
                                                                                        location);
 163  
 
 164  186
         embeddedComponents.put(id, embedded);
 165  
 
 166  186
         return embedded; // So that parameters can be filled in
 167  
     }
 168  
 
 169  
     public List<String> getEmbeddedComponentIds()
 170  
     {
 171  948
         List<String> result = CollectionFactory.newList();
 172  
 
 173  948
         if (embeddedComponents != null) result.addAll(embeddedComponents.keySet());
 174  
 
 175  948
         if (parentModel != null) result.addAll(parentModel.getEmbeddedComponentIds());
 176  
 
 177  948
         Collections.sort(result);
 178  
 
 179  948
         return result;
 180  
     }
 181  
 
 182  
     public EmbeddedComponentModel getEmbeddedComponentModel(String componentId)
 183  
     {
 184  714
         EmbeddedComponentModel result = InternalUtils.get(embeddedComponents, componentId);
 185  
 
 186  714
         if (result == null && parentModel != null) result = parentModel.getEmbeddedComponentModel(componentId);
 187  
 
 188  714
         return result;
 189  
     }
 190  
 
 191  
     public String getFieldPersistenceStrategy(String fieldName)
 192  
     {
 193  840
         String result = InternalUtils.get(persistentFields, fieldName);
 194  
 
 195  840
         if (result == null && parentModel != null) result = parentModel.getFieldPersistenceStrategy(fieldName);
 196  
 
 197  840
         if (result == null) throw new IllegalArgumentException(ModelMessages.missingPersistentField(fieldName));
 198  
 
 199  838
         return result;
 200  
     }
 201  
 
 202  
     public List<String> getPersistentFieldNames()
 203  
     {
 204  170
         return persistentFieldNameAllocator.getAllocatedIds();
 205  
     }
 206  
 
 207  
     public String setFieldPersistenceStrategy(String fieldName, String strategy)
 208  
     {
 209  152
         String logicalFieldName = persistentFieldNameAllocator.allocateId(fieldName);
 210  
 
 211  152
         if (persistentFields == null) persistentFields = CollectionFactory.newMap();
 212  
 
 213  152
         persistentFields.put(logicalFieldName, strategy);
 214  
 
 215  152
         return logicalFieldName;
 216  
     }
 217  
 
 218  
     public boolean isRootClass()
 219  
     {
 220  614
         return parentModel == null;
 221  
     }
 222  
 
 223  
     public void addMixinClassName(String mixinClassName)
 224  
     {
 225  74
         if (mixinClassNames == null) mixinClassNames = CollectionFactory.newList();
 226  
 
 227  74
         mixinClassNames.add(mixinClassName);
 228  74
     }
 229  
 
 230  
     public List<String> getMixinClassNames()
 231  
     {
 232  3000
         List<String> result = CollectionFactory.newList();
 233  
 
 234  3000
         if (mixinClassNames != null) result.addAll(mixinClassNames);
 235  
 
 236  3000
         if (parentModel != null) result.addAll(parentModel.getMixinClassNames());
 237  
 
 238  3000
         Collections.sort(result);
 239  
 
 240  3000
         return result;
 241  
     }
 242  
 
 243  
     public void enableSupportsInformalParameters()
 244  
     {
 245  220
         informalParametersSupported = true;
 246  220
     }
 247  
 
 248  
     public boolean getSupportsInformalParameters()
 249  
     {
 250  1028
         return informalParametersSupported;
 251  
     }
 252  
 
 253  
     public ComponentModel getParentModel()
 254  
     {
 255  1478
         return parentModel;
 256  
     }
 257  
 
 258  
     public boolean isMixinAfter()
 259  
     {
 260  655
         return mixinAfter;
 261  
     }
 262  
 
 263  
     public void setMixinAfter(boolean mixinAfter)
 264  
     {
 265  54
         this.mixinAfter = mixinAfter;
 266  54
     }
 267  
 
 268  
     public void setMeta(String key, String value)
 269  
     {
 270  22
         Defense.notBlank(key, "key");
 271  22
         Defense.notBlank(value, "value");
 272  
 
 273  22
         if (metaData == null) metaData = CollectionFactory.newCaseInsensitiveMap();
 274  
 
 275  
         // TODO: Error if duplicate?
 276  
 
 277  22
         metaData.put(key, value);
 278  22
     }
 279  
 
 280  
     public void addRenderPhase(Class renderPhase)
 281  
     {
 282  634
         Defense.notNull(renderPhase, "renderPhase");
 283  
 
 284  634
         if (handledRenderPhases == null) handledRenderPhases = CollectionFactory.newSet();
 285  
 
 286  634
         handledRenderPhases.add(renderPhase);
 287  634
     }
 288  
 
 289  
     public void addEventHandler(String eventType)
 290  
     {
 291  410
         if (handledEvents == null)
 292  208
             handledEvents = CollectionFactory.newCaseInsensitiveMap();
 293  
 
 294  410
         handledEvents.put(eventType, true);
 295  410
     }
 296  
 
 297  
     public String getMeta(String key)
 298  
     {
 299  1256
         String result = InternalUtils.get(metaData, key);
 300  
 
 301  1256
         if (result == null && parentModel != null) result = parentModel.getMeta(key);
 302  
 
 303  1256
         return result;
 304  
     }
 305  
 
 306  
     public Set<Class> getHandledRenderPhases()
 307  
     {
 308  4996
         Set<Class> result = CollectionFactory.newSet();
 309  
 
 310  4996
         if (parentModel != null)
 311  1331
             result.addAll(parentModel.getHandledRenderPhases());
 312  
 
 313  4996
         if (handledRenderPhases != null)
 314  4167
             result.addAll(handledRenderPhases);
 315  
 
 316  4996
         return result;
 317  
     }
 318  
 
 319  
     public boolean handlesEvent(String eventType)
 320  
     {
 321  340
         if (InternalUtils.get(handledEvents, eventType) != null) return true;
 322  
 
 323  322
         return parentModel == null
 324  
                ? false
 325  
                : parentModel.handlesEvent(eventType);
 326  
     }
 327  
 }