/* * Copyright (c) 2012-2014 Savoir Technologies, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.savoirtech.hecate.cql3.handler.def; import com.savoirtech.hecate.cql3.convert.ValueConverter; import com.savoirtech.hecate.cql3.convert.ValueConverterRegistry; import com.savoirtech.hecate.cql3.convert.def.DefaultValueConverterRegistry; import com.savoirtech.hecate.cql3.exception.HecateException; import com.savoirtech.hecate.cql3.handler.ArrayHandler; import com.savoirtech.hecate.cql3.handler.ColumnHandler; import com.savoirtech.hecate.cql3.handler.ColumnHandlerFactory; import com.savoirtech.hecate.cql3.handler.ListHandler; import com.savoirtech.hecate.cql3.handler.MapHandler; import com.savoirtech.hecate.cql3.handler.SetHandler; import com.savoirtech.hecate.cql3.handler.SimpleHandler; import com.savoirtech.hecate.cql3.handler.delegate.ColumnHandlerDelegate; import com.savoirtech.hecate.cql3.handler.delegate.PojoDelegate; import com.savoirtech.hecate.cql3.handler.delegate.ScalarDelegate; import com.savoirtech.hecate.cql3.meta.FacetMetadata; import com.savoirtech.hecate.cql3.meta.PojoMetadata; import com.savoirtech.hecate.cql3.meta.PojoMetadataFactory; import com.savoirtech.hecate.cql3.meta.def.DefaultPojoMetadataFactory; import com.savoirtech.hecate.cql3.util.GenericType; import org.apache.commons.lang3.Validate; import java.util.List; import java.util.Map; import java.util.Set; public class DefaultColumnHandlerFactory implements ColumnHandlerFactory { //---------------------------------------------------------------------------------------------------------------------- // Fields //---------------------------------------------------------------------------------------------------------------------- private final ValueConverterRegistry registry; private final PojoMetadataFactory pojoMetadataFactory; //---------------------------------------------------------------------------------------------------------------------- // Static Methods //---------------------------------------------------------------------------------------------------------------------- private static Class<?> elementType(GenericType genericType) { if (List.class.equals(genericType.getRawType())) { return genericType.getListElementType().getRawType(); } if (Set.class.equals(genericType.getRawType())) { return genericType.getSetElementType().getRawType(); } if (Map.class.equals(genericType.getRawType())) { return genericType.getMapValueType().getRawType(); } if (genericType.getRawType().isArray()) { return genericType.getArrayElementType().getRawType(); } return genericType.getRawType(); } //---------------------------------------------------------------------------------------------------------------------- // Constructors //---------------------------------------------------------------------------------------------------------------------- public DefaultColumnHandlerFactory() { this(DefaultValueConverterRegistry.defaultRegistry(), new DefaultPojoMetadataFactory()); } public DefaultColumnHandlerFactory(PojoMetadataFactory pojoMetadataFactory) { this(DefaultValueConverterRegistry.defaultRegistry(), pojoMetadataFactory); } public DefaultColumnHandlerFactory(ValueConverterRegistry registry, PojoMetadataFactory pojoMetadataFactory) { this.registry = registry; this.pojoMetadataFactory = pojoMetadataFactory; } //---------------------------------------------------------------------------------------------------------------------- // ColumnHandlerFactory Implementation //---------------------------------------------------------------------------------------------------------------------- @Override @SuppressWarnings("unchecked") public ColumnHandler<Object, Object> getColumnHandler(FacetMetadata facetMetadata) { final GenericType facetType = facetMetadata.getFacet().getType(); final Class<?> elementType = elementType(facetType); ValueConverter converter = registry.getValueConverter(elementType); if (converter != null) { return createColumnHandler(facetType, new ScalarDelegate(converter)); } else { final Class<?> pojoType = elementType(facetType); final PojoMetadata pojoMetadata = pojoMetadataFactory.getPojoMetadata(pojoType); return createColumnHandler(facetType, new PojoDelegate(pojoMetadata, facetMetadata, getIdentifierConverter(pojoMetadata))); } } //---------------------------------------------------------------------------------------------------------------------- // Other Methods //---------------------------------------------------------------------------------------------------------------------- private ColumnHandler createColumnHandler(GenericType facetType, ColumnHandlerDelegate delegate) { if (List.class.equals(facetType.getRawType())) { return new ListHandler(delegate); } if (Set.class.equals(facetType.getRawType())) { return new SetHandler(delegate); } if (Map.class.equals(facetType.getRawType())) { final Class<?> keyType = facetType.getMapKeyType().getRawType(); final ValueConverter keyConverter = Validate.notNull(registry.getValueConverter(keyType), "Invalid map key type %s (must be scalar).", keyType.getCanonicalName()); return new MapHandler(keyConverter, delegate); } if (facetType.getRawType().isArray()) { return new ArrayHandler(facetType.getRawType().getComponentType(), delegate); } return new SimpleHandler(delegate); } private ValueConverter getIdentifierConverter(PojoMetadata pojoMetadata) { final ValueConverter converter = registry.getValueConverter(pojoMetadata.getIdentifierFacet().getFacet().getType().getRawType()); if (converter == null) { throw new HecateException(String.format("Unable to cascade POJO type %s (non-scalar identifier).", pojoMetadata.getPojoType().getCanonicalName())); } return converter; } }