package org.om.core.impl.persistence.interceptor.handler; import org.om.core.api.annotation.LookupMode; import org.om.core.api.exception.MissingException; import org.om.core.api.exception.PathNotFoundException; import org.om.core.api.mapping.MappedField; import org.om.core.api.mapping.field.ReferenceMapping; 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.api.session.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Handles properties whose values are references to other entities. * * @author Jakob Külzer * */ public class ReferenceHandler implements ItemHandler { private static final Logger LOGGER = LoggerFactory.getLogger(ReferenceHandler.class); private final Session session; public ReferenceHandler(Session session) { this.session = session; } @Override public Object retrieve(MappedField mappedField, PersistenceAdapter adapter) { final ReferenceMapping mapping = (ReferenceMapping) mappedField.getMapping(); // TODO: Need better code here to handle locations Object id = adapter.resolve(mapping.getPath()); LOGGER.debug("Path (resolved) from mapping is {} ({})", mapping.getPath(), id); if (mapping.getLookupMode() == LookupMode.Reference) { LOGGER.trace("Field {} is a reference, retrieving value of local field to resolve reference...", mappedField.getName()); // We're using the value of the local property as the path to lookup // the object. final PersistenceResult result = adapter.getProperty(new ImmutablePersistenceRequest(mapping.getPath(), String.class, Mode.Relative)); if (result.hasResult() && result.getValue() != null) { id = result.getValue(); } else { id = MissingHandler.INSTANCE.retrieve(mappedField, adapter); } } LOGGER.trace("Retrieving reference to {} from {}", mappedField.getType(), id); try { return session.get(mapping.getImplementationType(), id); } catch (PathNotFoundException e) { switch (mappedField.getMissingStrategy()) { case ReturnNull: return null; case DefaultValue: // TODO: handle default value case ThrowException: default: // TODO: throw appropriate exception type throw new MissingException("Cannot find " + id + " while retrieving " + mappedField, e); } } } @Override public String toString() { return "ReferenceHandler [session=" + session + "]"; } }