Coverage Report - org.simpleframework.xml.transform.RegistryMatcher
 
Classes in this File Line Coverage Branch Coverage Complexity
RegistryMatcher
100%
21/21
83%
5/6
1.833
 
 1  
 /*
 2  
  * RegistryMatcher.java May 2011
 3  
  *
 4  
  * Copyright (C) 2011, Niall Gallagher <niallg@users.sf.net>
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License");
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
 15  
  * implied. See the License for the specific language governing 
 16  
  * permissions and limitations under the License.
 17  
  */
 18  
 
 19  
 package org.simpleframework.xml.transform;
 20  
 
 21  
 import org.simpleframework.xml.util.Cache;
 22  
 import org.simpleframework.xml.util.ConcurrentCache;
 23  
 
 24  
 /**
 25  
  * The <code>RegistryMatcher</code> provides a simple matcher backed
 26  
  * by a registry. Registration can be done to match a type to a
 27  
  * <code>Transform</code> class or instance. If a transform class is
 28  
  * registered an instance of it is created when requested using the
 29  
  * default no argument constructor of the type, it is then cached so 
 30  
  * it can be reused on future requests.
 31  
  * 
 32  
  * @author Niall Gallagher
 33  
  * 
 34  
  * @see org.simpleframework.xml.core.Persister
 35  
  */
 36  
 public class RegistryMatcher implements Matcher {
 37  
    
 38  
    /**
 39  
     * This is used to fetch transform instances by type.
 40  
     */
 41  
    private final Cache<Transform> transforms;
 42  
    
 43  
    /**
 44  
     * This is used to determine the transform  for a type.
 45  
     */
 46  
    private final Cache<Class> types;
 47  
    
 48  
    /**
 49  
     * Constructor for the <code>RegistryMatcher</code>. This is used
 50  
     * to create a matcher instance that can resolve a transform by
 51  
     * type and can also instantiate new transforms if required. It 
 52  
     * is essentially a convenience implementation.
 53  
     */
 54  1
    public RegistryMatcher() {
 55  1
       this.transforms = new ConcurrentCache<Transform>();
 56  1
       this.types = new ConcurrentCache<Class>();
 57  1
    }
 58  
    
 59  
    /**
 60  
     * This is used to bind a <code>Transform</code> type. The first 
 61  
     * time a transform is requested for the specified type a new 
 62  
     * instance of this <code>Transform</code> will be instantiated.
 63  
     * 
 64  
     * @param type this is the type to resolve the transform for
 65  
     * @param transform this is the transform type to instantiate
 66  
     */
 67  
    public void bind(Class type, Class transform) {
 68  2
       types.cache(type, transform);
 69  2
    }
 70  
    
 71  
    /**
 72  
     * This is used to bind a <code>Transform</code> instance to the
 73  
     * specified type. Each time a transform is requested for this
 74  
     * type the provided instance will be returned.
 75  
     * 
 76  
     * @param type this is the type to resolve the transform for
 77  
     * @param transform this transform instance to be used
 78  
     */
 79  
    public void bind(Class type, Transform transform) {
 80  1
       transforms.cache(type, transform);
 81  1
    }
 82  
    
 83  
    /**
 84  
     * This is used to match a <code>Transform</code> using the type
 85  
     * specified. If no transform can be acquired then this returns
 86  
     * a null value indicating that no transform could be found.
 87  
     * 
 88  
     * @param type this is the type to acquire the transform for
 89  
     * 
 90  
     * @return returns a transform for processing the type given
 91  
     */ 
 92  
    public Transform match(Class type) throws Exception {
 93  7
       Transform transform = transforms.fetch(type);
 94  
       
 95  7
       if(transform == null) {
 96  3
          return create(type);
 97  
       }
 98  4
       return transform;
 99  
    }
 100  
    
 101  
    /**
 102  
     * This is used to create a <code>Transform</code> using the type
 103  
     * specified. If no transform can be acquired then this returns
 104  
     * a null value indicating that no transform could be found.
 105  
     * 
 106  
     * @param type this is the type to acquire the transform for
 107  
     * 
 108  
     * @return returns a transform for processing the type given
 109  
     */ 
 110  
    private Transform create(Class type) throws Exception {
 111  3
       Class factory = types.fetch(type);
 112  
       
 113  3
       if(factory != null) {
 114  2
          return create(type, factory);
 115  
       }
 116  1
       return null;
 117  
    }
 118  
    
 119  
    /**
 120  
     * This is used to create a <code>Transform</code> using the type
 121  
     * specified. If the transform can not be instantiated then this
 122  
     * will throw an exception. If it can then it is cached.
 123  
     * 
 124  
     * @param type this is the type to acquire the transform for
 125  
     * @param factory the class for instantiating the transform
 126  
     * 
 127  
     * @return returns a transform for processing the type given
 128  
     */ 
 129  
    private Transform create(Class type, Class factory) throws Exception {
 130  2
       Object value = factory.newInstance();
 131  2
       Transform transform = (Transform)value;
 132  
          
 133  2
       if(transform != null) {
 134  2
          transforms.cache(type, transform);
 135  
       }
 136  2
       return transform;
 137  
    }
 138  
 }