Coverage Report - org.seasar.cubby.dxo.impl.RequestParameterConverterFactoryImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
RequestParameterConverterFactoryImpl
94%
58/62
67%
20/30
0
RequestParameterConverterFactoryImpl$1
N/A
N/A
0
RequestParameterConverterFactoryImpl$DisregardExceptionConverterWrapper
64%
7/11
N/A
0
 
 1  
 /*
 2  
  * Copyright 2004-2008 the Seasar Foundation and the Others.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 13  
  * either express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 package org.seasar.cubby.dxo.impl;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.HashMap;
 20  
 import java.util.List;
 21  
 import java.util.Map;
 22  
 
 23  
 import org.seasar.extension.dxo.converter.ConversionContext;
 24  
 import org.seasar.extension.dxo.converter.Converter;
 25  
 import org.seasar.extension.dxo.converter.impl.ConverterFactoryImpl;
 26  
 import org.seasar.framework.container.ComponentDef;
 27  
 import org.seasar.framework.container.S2Container;
 28  
 import org.seasar.framework.container.factory.S2ContainerFactory;
 29  
 import org.seasar.framework.log.Logger;
 30  
 import org.seasar.framework.util.DisposableUtil;
 31  
 import org.seasar.framework.util.ResourceUtil;
 32  
 
 33  
 /**
 34  
  * リクエストのパラメータとアクションのプロパティとの変換に使用する{@link org.seasar.extension.dxo.converter.Converter コンバータ}のファクトリクラスです。
 35  
  * 
 36  
  * @author baba
 37  
  * @since 1.0.0
 38  
  */
 39  36
 public class RequestParameterConverterFactoryImpl extends ConverterFactoryImpl {
 40  
 
 41  
         /** ロガー。 */
 42  1
         private static final Logger logger = Logger
 43  
                         .getLogger(RequestParameterConverterFactoryImpl.class);
 44  
 
 45  
         /** 空のコンバータの配列。 */
 46  1
         private static final Converter[] EMPTY_CONVERTER_ARRAY = new Converter[0];
 47  
 
 48  
         /** コンバータのラッパのキャッシュ。 */
 49  1
         private static final Map<Converter, Converter> wrapperCache = new HashMap<Converter, Converter>();
 50  
 
 51  
         /** コンバータが定義されたコンテナのパス。 */
 52  36
         private final List<String> converterContainerPaths = new ArrayList<String>();
 53  
 
 54  
         /** コンバータが定義されたコンテナ。 */
 55  36
         private final List<S2Container> containers = new ArrayList<S2Container>();
 56  
 
 57  
         /** アプリケーションで定義したコンバータを使用するかどうかを示します。 */
 58  36
         private boolean includeApplicationConverters = true;
 59  
 
 60  
         /** 初期化されたかどうかを示します。 */
 61  36
         private boolean initialized = false;
 62  
 
 63  
         /**
 64  
          * コンバータが定義されたコンテナのパスを追加します。
 65  
          * 
 66  
          * @param converterContainerPath
 67  
          *            コンバータが定義されたコンテナのパス
 68  
          */
 69  
         public void addConverterContainerPath(final String converterContainerPath) {
 70  108
                 this.converterContainerPaths.add(converterContainerPath);
 71  108
         }
 72  
 
 73  
         /**
 74  
          * アプリケーションで定義したコンバータを使用するかどうかを設定します。
 75  
          * 
 76  
          * @param includeApplicationConverters
 77  
          *            アプリケーションで定義したコンバータを使用する場合は <code>true</code>、そうでない場合は
 78  
          *            <code>false</code>
 79  
          */
 80  
         public void setIncludeApplicationConverters(
 81  
                         final boolean includeApplicationConverters) {
 82  36
                 this.includeApplicationConverters = includeApplicationConverters;
 83  36
         }
 84  
 
 85  
         /**
 86  
          * {@inheritDoc}
 87  
          */
 88  
         @Override
 89  
         public void initialize() {
 90  56
                 if (initialized) {
 91  47
                         return;
 92  
                 }
 93  
 
 94  9
                 super.initialize();
 95  
 
 96  9
                 final Map<Class<? extends Converter>, Converter> converterMap = new HashMap<Class<? extends Converter>, Converter>();
 97  9
                 for (final String path : this.converterContainerPaths) {
 98  27
                         if (ResourceUtil.isExist(path)) {
 99  27
                                 if (logger.isDebugEnabled()) {
 100  27
                                         logger.log("DCUB0011", new Object[] { path });
 101  
                                 }
 102  27
                                 final S2Container container = S2ContainerFactory.create(path);
 103  27
                                 containers.add(container);
 104  
                                 for (final ComponentDef componentDef : container
 105  252
                                                 .findAllComponentDefs(Converter.class)) {
 106  225
                                         final Converter converter = (Converter) componentDef
 107  
                                                         .getComponent();
 108  225
                                         converterMap.put(converter.getClass(), converter);
 109  225
                                         if (logger.isDebugEnabled()) {
 110  225
                                                 logger.log("DCUB0010", new Object[] { converter });
 111  
                                         }
 112  
                                 }
 113  27
                                 if (logger.isDebugEnabled()) {
 114  27
                                         logger
 115  
                                                         .log("DCUB0012",
 116  
                                                                         new Object[] { container.getPath() });
 117  
                                 }
 118  27
                         }
 119  
                 }
 120  
 
 121  9
                 if (includeApplicationConverters) {
 122  9
                         final List<Converter> converterList = new ArrayList<Converter>(
 123  
                                         converterMap.values());
 124  9
                         if (logger.isDebugEnabled()) {
 125  9
                                 logger.log("DCUB0013", null);
 126  
                         }
 127  207
                         for (final Converter converter : converters) {
 128  198
                                 if (!converterMap.containsKey(converter.getClass())) {
 129  0
                                         converterList.add(converter);
 130  0
                                         if (logger.isDebugEnabled()) {
 131  0
                                                 logger.log("DCUB0010", new Object[] { converter });
 132  
                                         }
 133  
                                 }
 134  
                         }
 135  9
                         if (logger.isDebugEnabled()) {
 136  9
                                 logger.log("DCUB0014", null);
 137  
                         }
 138  9
                         converters = converterList.toArray(EMPTY_CONVERTER_ARRAY);
 139  9
                 } else {
 140  0
                         converters = converterMap.values().toArray(EMPTY_CONVERTER_ARRAY);
 141  
                 }
 142  
 
 143  9
                 DisposableUtil.add(this);
 144  9
                 initialized = true;
 145  9
         }
 146  
 
 147  
         /**
 148  
          * {@inheritDoc}
 149  
          */
 150  
         @Override
 151  
         public void dispose() {
 152  18
                 wrapperCache.clear();
 153  18
                 for (final S2Container container : this.containers) {
 154  27
                         container.destroy();
 155  
                 }
 156  18
                 containers.clear();
 157  18
                 super.dispose();
 158  18
                 initialized = false;
 159  18
         }
 160  
 
 161  
         /**
 162  
          * {@inheritDoc}
 163  
          * <p>
 164  
          * ここで生成されるコンバータは、{@link Converter#convert(Object, Class, ConversionContext)}の実行時に例外が発生した場合は
 165  
          * <code>null</code> を返すようにラップされます。
 166  
          * </p>
 167  
          */
 168  
         @Override
 169  
         @SuppressWarnings("unchecked")
 170  
         public Converter getConverter(final Class sourceClass, final Class destClass) {
 171  28
                 initialize();
 172  28
                 final Converter converter = super.getConverter(sourceClass, destClass);
 173  
                 final Converter wrapper;
 174  28
                 if (wrapperCache.containsKey(converter)) {
 175  9
                         wrapper = wrapperCache.get(converter);
 176  
                 } else {
 177  19
                         wrapper = new DisregardExceptionConverterWrapper(converter);
 178  19
                         wrapperCache.put(converter, wrapper);
 179  
                 }
 180  28
                 return wrapper;
 181  
         }
 182  
 
 183  
         /**
 184  
          * 変換時の例外を無視するように{@link Converter}をラップするクラスです。
 185  
          * 
 186  
          * @author baba
 187  
          */
 188  36
         private static class DisregardExceptionConverterWrapper implements
 189  
                         Converter {
 190  
 
 191  
                 /** ラップするコンバータ。 */
 192  
                 private final Converter converter;
 193  
 
 194  
                 /**
 195  
                  * インスタンス化します。
 196  
                  * 
 197  
                  * @param converter
 198  
                  *            ラップするコンバータ
 199  
                  */
 200  19
                 private DisregardExceptionConverterWrapper(final Converter converter) {
 201  19
                         this.converter = converter;
 202  19
                 }
 203  
 
 204  
                 /**
 205  
                  * {@inheritDoc}
 206  
                  * <p>
 207  
                  * 変換時に例外が発生した場合は <code>null</code> を返します。
 208  
                  * </p>
 209  
                  */
 210  
                 @SuppressWarnings("unchecked")
 211  
                 public Object convert(final Object source, final Class destClass,
 212  
                                 final ConversionContext context) {
 213  
                         try {
 214  23
                                 return converter.convert(source, destClass, context);
 215  0
                         } catch (final Exception e) {
 216  0
                                 return null;
 217  
                         }
 218  
                 }
 219  
 
 220  
                 /**
 221  
                  * {@inheritDoc}
 222  
                  * 
 223  
                  * @see #convert(Object, Class, ConversionContext)
 224  
                  */
 225  
                 public void convert(final Object source, final Object dest,
 226  
                                 final ConversionContext context) {
 227  5
                         converter.convert(source, dest, context);
 228  5
                 }
 229  
 
 230  
                 /**
 231  
                  * {@inheritDoc}
 232  
                  */
 233  
                 @SuppressWarnings("unchecked")
 234  
                 public Class getDestClass() {
 235  0
                         return converter.getDestClass();
 236  
                 }
 237  
 
 238  
                 /**
 239  
                  * {@inheritDoc}
 240  
                  */
 241  
                 @SuppressWarnings("unchecked")
 242  
                 public Class[] getSourceClasses() {
 243  0
                         return converter.getSourceClasses();
 244  
                 }
 245  
 
 246  
         }
 247  
 
 248  
 }