Clover coverage report - Code Coverage for tapestry-annotations release 4.0-rc-2
Coverage timestamp: Sat Dec 17 2005 09:47:59 PST
file stats: LOC: 97   Methods: 3
NCLOC: 49   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
MetaAnnotationWorker.java 83.3% 100% 100% 96.9%
coverage coverage
 1    // Copyright 2005 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.tapestry.annotations;
 16   
 17    import java.util.ArrayList;
 18    import java.util.Collections;
 19    import java.util.List;
 20   
 21    import org.apache.hivemind.ApplicationRuntimeException;
 22    import org.apache.hivemind.Location;
 23    import org.apache.tapestry.enhance.EnhancementOperation;
 24    import org.apache.tapestry.spec.IComponentSpecification;
 25   
 26    /**
 27    * Recognizes the {@link org.apache.tapestry.annotations.Meta} annotation, and converts it into
 28    * properties on the specification. It is desirable to have meta data in base classes be "merged"
 29    * with meta data from sub classes, with the sub classes overriding any conflicting elements from
 30    * the base class. What we do is work our way up the inheritance tree to java.lang.Object and work
 31    * with each Meta annotation we find.
 32    *
 33    * @author Howard M. Lewis Ship
 34    * @since 4.0
 35    */
 36    public class MetaAnnotationWorker implements ClassAnnotationEnhancementWorker
 37    {
 38   
 39  3 public void performEnhancement(EnhancementOperation op, IComponentSpecification spec,
 40    Class baseClass, Location location)
 41    {
 42  3 List<Meta> metas = assembleMetas(baseClass);
 43   
 44  3 for (Meta meta : metas)
 45  4 applyPropertiesFromMeta(meta, spec, location);
 46    }
 47   
 48  3 private List<Meta> assembleMetas(Class baseClass)
 49    {
 50  3 Class searchClass = baseClass;
 51  3 List<Meta> result = new ArrayList<Meta>();
 52  3 Meta lastMeta = null;
 53   
 54  3 while (true)
 55    {
 56  7 Meta meta = (Meta) searchClass.getAnnotation(Meta.class);
 57   
 58    // When reach a class that doesn't define or inherit a @Meta, we're done
 59  7 if (meta == null)
 60  3 break;
 61   
 62    // Cheap approach, based on annotation inheritance, for determining
 63    // whether a meta is already in the result list
 64   
 65  4 if (meta != lastMeta)
 66  4 result.add(meta);
 67   
 68  4 searchClass = searchClass.getSuperclass();
 69    }
 70   
 71  3 Collections.reverse(result);
 72   
 73  3 return result;
 74    }
 75   
 76  4 private void applyPropertiesFromMeta(Meta meta, IComponentSpecification spec, Location location)
 77    {
 78  4 String[] pairs = meta.value();
 79   
 80  4 for (String pair : pairs)
 81    {
 82  6 int equalx = pair.indexOf('=');
 83   
 84    // The only big problem is that the location will be the location of the @Meta in
 85    // the subclass, even if the @Meta with a problem is from a base class.
 86   
 87  6 if (equalx < 0)
 88  1 throw new ApplicationRuntimeException(AnnotationMessages.missingEqualsInMeta(pair),
 89    location, null);
 90   
 91  5 String key = pair.substring(0, equalx);
 92  5 String value = pair.substring(equalx + 1);
 93   
 94  5 spec.setProperty(key, value);
 95    }
 96    }
 97    }