001    package org.nakedobjects.applib.query;
002    
003    import java.util.Collections;
004    import java.util.HashMap;
005    import java.util.Map;
006    
007    
008    /**
009     * Default implementation of {@link Query} that supports
010     * parameter/argument values, along with a query name. 
011     */
012    public class QueryDefault<T> extends QueryAbstract<T> {
013    
014            private static final long serialVersionUID = 1L;
015    
016            /**
017             * Convenience factory method, preferable to {@link #QueryDefault(Class, String, Object...) constructor}
018             * because will automatically genericize. 
019             */
020            public static <Q> QueryDefault<Q> create(Class<Q> resultType, final String queryName,
021                            final Object... paramArgs) {
022                    return new QueryDefault<Q>(resultType, queryName, paramArgs);
023            }
024    
025            /**
026             * Convenience factory method, preferable to {@link #QueryDefault(Class, String, Map) constructor}
027             * because will automatically genericize. 
028             */
029            public static <Q> QueryDefault<Q> create(Class<Q> resultType, final String queryName,
030                            final Map<String, Object> argumentsByParameterName) {
031                    return new QueryDefault<Q>(resultType, queryName, argumentsByParameterName);
032            }
033    
034    
035            /**
036             * Converts a list of objects [a, 1, b, 2] into a map {a -> 1; b -> 2}
037             */
038            private static Map<String, Object> asMap(Object[] paramArgs) {
039                    HashMap<String, Object> map = new HashMap<String, Object>();
040                    boolean param = true;
041                    String paramStr = null;
042                    for (Object paramArg : paramArgs) {
043                            if (param) {
044                                    if (paramArg instanceof String) {
045                                            paramStr = (String) paramArg;
046                                    } else {
047                                            throw new IllegalArgumentException(
048                                                            "Parameter must be a string");
049                                    }
050                            } else {
051                                    Object arg = paramArg;
052                                    map.put(paramStr, arg);
053                                    paramStr = null;
054                            }
055                            param = !param;
056                    }
057                    if (paramStr != null) {
058                            throw new IllegalArgumentException(
059                                            "Must have equal number of parameters and arguments");
060                    }
061                    return map;
062            }
063    
064            
065            private final String queryName;
066            private final Map<String, Object> argumentsByParameterName;
067    
068            public QueryDefault(Class<T> resultType, final String queryName,
069                            final Object... paramArgs) {
070                    this(resultType, queryName, asMap(paramArgs));
071            }
072    
073            public QueryDefault(Class<T> resultType, final String queryName,
074                            final Map<String, Object> argumentsByParameterName) {
075                    super(resultType);
076                    this.queryName = queryName;
077                    this.argumentsByParameterName = argumentsByParameterName;
078            }
079    
080            public String getQueryName() {
081                    return queryName;
082            }
083    
084            public Map<String, Object> getArgumentsByParameterName() {
085                    return Collections.unmodifiableMap(argumentsByParameterName);
086            }
087    
088            public String getDescription() {
089                    return getQueryName() + " with " + getArgumentsByParameterName();
090            }
091    
092    }
093    // Copyright (c) Naked Objects Group Ltd.