/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ package com.db4o.qlin; import com.db4o.foundation.*; import com.db4o.reflect.*; import com.db4o.reflect.core.*; /** * static import support class for {@link QLin} queries. * @since 8.0 */ public class QLinSupport { /** * returns a prototype object for a specific class * to be passed to the where expression of a QLin * query. * @see QLin#where(Object) */ public static <T> T prototype(Class<T> clazz){ try{ return _prototypes.prototypeForClass(clazz); } catch(PrototypesException ex){ throw new QLinException(ex); } } /** * sets the context for the next query on this thread. * This method should never have to be called manually. * The framework should set the context up. */ public static void context(ReflectClass claxx){ _context.value(claxx); } /** * sets the context for the next query on this thread. * This method should never have to be called manually. * The framework should set the context up. */ public static void context(Class clazz){ _context.value(ReflectorUtils.reflectClassFor(_prototypes.reflector(), clazz)); } /** * shortcut for the {@link #prototype(Class)} method. */ public static <T> T p(Class<T> clazz){ return prototype(clazz); } /** * parameter for {@link QLin#orderBy(Object, QLinOrderByDirection)} */ public static QLinOrderByDirection ascending(){ return QLinOrderByDirection.ASCENDING; } /** * parameter for {@link QLin#orderBy(Object, QLinOrderByDirection)} */ public static QLinOrderByDirection descending(){ return QLinOrderByDirection.DESCENDING; } /** * public for implementors, do not use directly */ public static Iterator4<String> backingFieldPath(Object expression){ checkForNull(expression); if(expression instanceof ReflectField){ return Iterators.iterate( ((ReflectField)expression).getName()); } Iterator4 path = _prototypes.backingFieldPath(_context.value(), expression); if(path != null){ return path; } return Iterators.iterate(fieldByFieldName(expression).getName()); } /** * converts an expression to a single field. */ public static ReflectField field(Object expression){ checkForNull(expression); if(expression instanceof ReflectField){ return (ReflectField)expression; } Iterator4 path = _prototypes.backingFieldPath(_context.value(), expression); if(path != null){ if(path.moveNext()){ expression = path.current(); } if(path.moveNext()){ path.reset(); throw new QLinException("expression can not be converted to a single field. It evaluates to: " + Iterators.join(path, "[", "]", ", ")); } } return fieldByFieldName(expression); } private static ReflectField fieldByFieldName(Object expression) { if(expression instanceof String){ ReflectField field = ReflectorUtils.field(_context.value(), (String)expression); if(field != null){ return field; } } throw new QLinException("expression can not be mapped to a field"); } private static void checkForNull(Object expression) { if(expression == null){ throw new QLinException("expression can not be null"); } } private static final boolean IGNORE_TRANSIENT_FIELDS = true; private static final int RECURSION_DEPTH = 4; private static final Prototypes _prototypes = new Prototypes(Prototypes.defaultReflector(),RECURSION_DEPTH, IGNORE_TRANSIENT_FIELDS); private static final DynamicVariable<ReflectClass> _context = DynamicVariable.newInstance(); }