EMMA Coverage Report (generated Tue Feb 12 22:23:49 ICT 2008)
[all classes][net.sourceforge.hiveutils.service.impl]

COVERAGE SUMMARY FOR SOURCE FILE [AdapterBuilderFactory.java]

nameclass, %method, %block, %line, %
AdapterBuilderFactory.java100% (1/1)100% (5/5)73%  (144/198)76%  (41/54)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AdapterBuilderFactory100% (1/1)100% (5/5)73%  (144/198)76%  (41/54)
handleExceptionMapper (Object, ExceptionMapper, boolean, Log): ExceptionMapper 100% (1/1)28%  (5/18)33%  (2/6)
handleExceptionMapping (Object, ClassMatcher, ExceptionMapper, Log): boolean 100% (1/1)50%  (32/64)62%  (10/16)
handleBuilderParameter (Object, BuilderParameter, Log): BuilderParameter 100% (1/1)77%  (10/13)80%  (4/5)
createCoreServiceImplementation (ServiceImplementationFactoryParameters): Object 100% (1/1)94%  (94/100)92%  (24/26)
AdapterBuilderFactory (): void 100% (1/1)100% (3/3)100% (1/1)

1//  Copyright 2004-2007 Jean-Francois Poilpret
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 
15package net.sourceforge.hiveutils.service.impl;
16 
17import java.util.Iterator;
18import java.util.Map;
19 
20import org.apache.commons.logging.Log;
21import org.apache.hivemind.ServiceImplementationFactory;
22import org.apache.hivemind.ServiceImplementationFactoryParameters;
23import org.apache.hivemind.service.impl.BuilderFactoryLogic;
24import org.apache.hivemind.service.impl.BuilderParameter;
25 
26import net.sourceforge.hiveutils.service.ExceptionMapper;
27import net.sourceforge.hiveutils.util.ClassMatcher;
28import net.sourceforge.hiveutils.util.DefaultMethodMappingBuilder;
29import net.sourceforge.hiveutils.util.MethodMappingBuilder;
30import net.sourceforge.hiveutils.util.MethodMappingErrorHandler;
31 
32/**
33 * Service Factory that wraps an implementation class in a proxy object that
34 * will filter or convert exceptions thrown by its methods.
35 * <p>
36 * As a matter of fact, such a factory also enables to make a POJO service
37 * implementation, with no service interface, usable by Hivemind, by just
38 * creating an interface with all public methods of the POJO, and an empty
39 * ExceptionMapper.
40 *
41 * @author Jean-Francois Poilpret
42 */
43public class AdapterBuilderFactory implements ServiceImplementationFactory
44{
45        public Object        createCoreServiceImplementation(
46                                                ServiceImplementationFactoryParameters factoryParams)
47        {
48                Log serviceLog = factoryParams.getLog();
49                Class serviceInterface = factoryParams.getServiceInterface();
50 
51                // Analyse parameters
52                // builderParam maps to the <construct> tag and is passed later on to
53                // BuilderFactoryLogic class
54                BuilderParameter builderParam = null;
55                // matcher will contain all exception mappings contained in parameters
56                ClassMatcher matcher = new ClassMatcher();
57                ExceptionMapper mapper = null;
58                boolean hasMapping = false;
59                Iterator i = factoryParams.getParameters().iterator();
60                while (i.hasNext())
61                {
62                        Object param = i.next();
63 
64                        builderParam = handleBuilderParameter(param, builderParam, serviceLog);
65 
66                        if (handleExceptionMapping(param, matcher, mapper, serviceLog))
67                        {
68                                hasMapping = true;
69                        }
70 
71                        mapper = handleExceptionMapper(param, mapper, hasMapping, serviceLog);
72                }
73 
74                if (builderParam == null)
75                {
76                        // Log error and then let BuilderFactoryLogic handle the problem
77                        serviceLog.error("No construct parameter defined");
78                }
79                if (mapper == null && !hasMapping)
80                {
81                        // Log warning (we can go on but all exceptions will be passed
82                        // "as is"
83                        serviceLog.warn("No exception mapping defined");
84                }
85 
86                // Use the existing BuilderFactoryLogic to create the actual service                
87                BuilderFactoryLogic logic = new BuilderFactoryLogic(factoryParams, 
88                                                                                                                        builderParam);
89                Object service = logic.createService();
90                
91                // Create the exception mapper from parameters and instantiate
92                // the exception-mapping proxy around the service
93                if (mapper == null)
94                {
95                        mapper = new DefaultExceptionMapper(serviceLog, matcher);
96                }
97 
98                // Create the methods mapping
99                MethodMappingBuilder methodMapper = new DefaultMethodMappingBuilder();
100                MethodMappingErrorHandler errorHandler =
101                                                        new DefaultMethodMappingErrorHandler(serviceLog);
102                
103                // Find the mapping from interface methods to implementation methods
104                Map methods = methodMapper.buildMapping(serviceInterface, 
105                                                                                                service.getClass(),
106                                                                                                errorHandler);
107 
108                return AdapterProxyFactoryHelper.createProxy(        serviceInterface,
109                                                                                                                service,
110                                                                                                                methods,
111                                                                                                                mapper);
112        }
113        
114        private BuilderParameter handleBuilderParameter(Object                                param, 
115                                                                                                        BuilderParameter        builderParam,
116                                                                                                        Log                                        serviceLog)
117        {
118                if (param instanceof BuilderParameter)
119                {
120                        if (builderParam == null)
121                        {
122                                return (BuilderParameter) param;
123                        }
124                        // Log warning, but don't account for second "construct" tag
125                        serviceLog.warn("Duplicate <construct> parameters are not accounted for");
126                }
127                return builderParam;
128        }
129        
130        private boolean        handleExceptionMapping(        Object                        param,
131                                                                                        ClassMatcher        matcher,
132                                                                                        ExceptionMapper        mapper,
133                                                                                        Log                                serviceLog)
134        {
135                if (param instanceof ExceptionMappingContribution)
136                {
137                        if (mapper == null)
138                        {
139                                ExceptionMappingContribution map =
140                                                        (ExceptionMappingContribution) param;
141                                // Check that from and to are Throwable
142                                boolean classesAreExceptions = true;
143                                if (!Throwable.class.isAssignableFrom(map.getFrom()))
144                                {
145                                        // This is only a warning because we do not account for them
146                                        serviceLog.warn(map.getFrom().getName() + " is not a Throwable");
147                                        classesAreExceptions = false;
148                                }
149                                if (!Throwable.class.isAssignableFrom(map.getTo()))
150                                {
151                                        // This is only a warning because we do not account for them
152                                        serviceLog.warn(map.getTo().getName() + " is not a Throwable");
153                                        classesAreExceptions = false;
154                                }
155                                if (classesAreExceptions)
156                                {
157                                        matcher.put(map.getFrom(), map.getTo());
158                                        return true;
159                                }
160                        }
161                        else
162                        {
163                                // Log warning, but don't account for this "exception-mapping" tag
164                                serviceLog.warn("<exception-mapping> not accounted for because it " +
165                                                                "conflicts with a <exception-mapper> tag");
166                        }
167                }
168                return false;
169        }
170        
171        private ExceptionMapper        handleExceptionMapper(        Object                        param,
172                                                                                                        ExceptionMapper        mapper,
173                                                                                                        boolean                        hasMapping,
174                                                                                                        Log                                serviceLog)
175        {
176                if (param instanceof ExceptionMapperContribution)
177                {
178                        if (mapper == null && !hasMapping)
179                        {
180                                ExceptionMapperContribution map =
181                                                        (ExceptionMapperContribution) param;
182                                return map.getMapper();
183                        }
184                        // Log warning, but don't account for this "exception-mapper" tag
185                        serviceLog.warn("<exception-mapper> not accounted for because it " +
186                                                        "conflicts with another tag");
187                }
188                return mapper;
189        }
190}

[all classes][net.sourceforge.hiveutils.service.impl]
EMMA 2.0.5312 (C) Vladimir Roubtsov