package org.om.core.impl.persistence.interceptor.handler; import java.beans.PropertyEditor; import java.beans.PropertyEditorManager; import org.om.core.api.exception.MappingException; import org.om.core.api.exception.ObjectMapperException; import org.om.core.api.exception.PersistenceLayerException; import org.om.core.api.mapping.MappedField; import org.om.core.api.mapping.field.PropertyMapping; import org.om.core.api.persistence.PersistenceAdapter; import org.om.core.api.persistence.interceptor.handler.ItemHandler; import org.om.core.api.persistence.request.ImmutablePersistenceRequest; import org.om.core.api.persistence.request.Mode; import org.om.core.api.persistence.result.PersistenceResult; import org.om.core.impl.util.ClassUtils; /** * Property handler for primitive or autoboxed types. Will automatically perform * type conversion if necessary. * * TODO: This doesn't have support for parsing dates. * * @author Jakob Külzer * */ public class PrimitiveHandler implements ItemHandler { public Object retrieve(MappedField mappedField, PersistenceAdapter adapter) { if (!(mappedField.getMapping() instanceof PropertyMapping)) throw new MappingException("Expected PropertyMapping for " + mappedField + " but got " + mappedField.getClass()); final PropertyMapping mapping = (PropertyMapping) mappedField.getMapping(); final PersistenceResult result; try { result = adapter.getProperty(new ImmutablePersistenceRequest(mapping.getPropertyName(), mappedField.getType(), Mode.Relative)); } catch (PersistenceLayerException e) { throw new ObjectMapperException("Could not retrieve primitive for " + mappedField, e); } if (result == null) throw new IllegalStateException("PersistenceAdapter returned null. This should not happen."); final Object input; if (result.hasResult()) { input = result.getValue(); } else { input = MissingHandler.INSTANCE.retrieve(mappedField, adapter); } // If we get a null, we can just return null, no type checking // necessary. if (input == null) return null; // If the returned object already has the correct type, just return it. if (mappedField.getType() == input.getClass()) { return input; } // If the input is a primitive type, it's probably safe to return. // TODO: I just wrote probably. So it's probably a bad thing. if (ClassUtils.isPrimitiveOrAutoboxed(mappedField.getType()) && ClassUtils.isPrimitiveOrAutoboxed(input.getClass())) return input; // This is ugly, but necessary as boxed types are not the same class // as primitive types. // If the returned object is a String, we'll have to parse it. if (String.class.equals(input.getClass())) { // This is real ugly: PropertyEditors return boxed primitive // types instead of exactly what you ask for. final PropertyEditor editor = PropertyEditorManager.findEditor(mappedField.getType()); editor.setAsText((String) input); return editor.getValue(); } throw new IllegalStateException("We have an unhandled type " + mappedField.getType() + "."); } }