1. Java / Говнокод #10175

    +66

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    95. 95
    96. 96
    97. 97
    package util;
    
    import play.db.jpa.JPA;
    import play.db.jpa.Model;
    import play.mvc.Http;
    import play.mvc.Router;
    import play.mvc.Scope;
    
    import javax.persistence.Query;
    import javax.persistence.EntityManager;
    import java.lang.reflect.Field;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * Page of results for model classes (because paginate module looks too buggy).
     * It is not generic solution but it fits the needs.
     * @author <a href="mailto:[email protected]">Roman Kashitsyn</a>
     */
    public class Page<M extends Model> implements PageBuilder<M> {
        
        public static final int MAX_PAGE_SIZE = 20;
        public static final int DEFAULT_PAGE_SIZE = 10;
        public static final int DEFAULT_PAGE_NUMBER = 1;
    
        public static final String PAGE_NUMBER_PARAM = "page";
        public static final String PAGE_SIZE_PARAM = "psize";
        public static final String ORDER_PARAM = "order";
        public static final String ORDER_BY_PARAM = "orderBy";
        
        private static final String ASC = "asc";
        private static final String DESC = "desc";
        private static final List<String> ALLOWED_ORDERS = Arrays.asList(ASC, DESC);
    
        private int pageSize = DEFAULT_PAGE_SIZE;
        private int pageNumber = DEFAULT_PAGE_NUMBER;
        private int total;
        private String orderBy;
        private String order;
        private final Http.Request request;
        private final Map<String, Object> params;
        private List<M> results;
        private final Class<M> clazz;
    
        public class SizeSwitcher {
            private final Map<String, Object> params;
    
            private SizeSwitcher() {
                // making defensive copy
                params = new HashMap<String, Object>(Page.this.params);
                // list of different size should always begin with 1 page
                params.put(PAGE_NUMBER_PARAM, 1);
            }
    
            public String urlToSwitchSize(int newSize) {
                params.put(PAGE_SIZE_PARAM, newSize);
                return Router.reverse(Page.this.request.action, params).url;
            }
    
            public int currentSize() {
                return Page.this.pageSize;
            }
        }
    
        private Page(Class<M> clazz) {
            this.clazz = clazz;
            request = Http.Request.current();
            params = new HashMap<String, Object>(Scope.Params.current().allSimple());
        }
        
        public static <M extends Model> PageBuilder<M> of(Class<M> modelClass) {
            return new Page<M>(modelClass);
        }
        
        public PageBuilder<M> withParams(Map<?, ?> params) {
            pageNumber = limit(params.get(PAGE_NUMBER_PARAM), pageNumber, Integer.MAX_VALUE);
            pageSize = limit(params.get(PAGE_SIZE_PARAM), pageSize, MAX_PAGE_SIZE);
            Object orderByParam = params.get(ORDER_BY_PARAM);
            if (orderByParam != null) {
                orderBy(getSingleValue(orderByParam).toString());
            }
            Object orderParam = params.get(ORDER_PARAM);
            if (orderParam != null) {
                String proposedValue = getSingleValue(orderParam).toString();
                if (ALLOWED_ORDERS.contains(proposedValue)) {
                    order = getSingleValue(orderParam).toString();
                }
            }
            return this;
        }
    
        public PageBuilder<M> withNumber(int num) {
            this.pageNumber = num;
            return this;
        }

    Запостил: Govnisti_Diavol, 03 Мая 2012

    Комментарии (14) RSS

    • TypicalFluentClass.java
      Ответить
    • На самом деле так на джаве пишут немногие.
      >private Page(Class<M> clazz)
      >withParams
      >of
      Видно, что автор читал много сырцов либ. Хороший стиль.
      >Router.reverse(Page.this.request.action , params).url
      >url
      Блин, даже public-поле. Одобряю.
      ___________
      Сайтом ошибся.
      Ответить
      • > url
        > даже public-поле
        Авторы play! сознательно упростили многие вещи и пишут код нет так, как "принято". Поля всех моделей, кстати, тоже public советуют делать. Борются с бойлерплэйтом, наверное.
        Ответить
        • Я только сейчас понял кто автор кода.

          >упростили многие вещи и пишут код нет так, как "принято"
          И правильно. Раз модификатор public введен в язык, почему бы им не воспользоваться!?
          Ответить
    • а в чем претензия?
      Ответить
    • getSingleValue(someThing).toString();

      я бы это в хелпер-метод вынес
      Ответить
    • Написано за пару часов, работает и даже вроде не ломается, если пользователь захочет поиграться с URL-ками на сайте. Есть пара некрасивых мест (жонглирование orderby при составлении запроса, к примеру), но в топик оно не попало. Конструктивные предложения принимаются. Остальной фарш тут
      https://github.com/roman-kashitsyn/user-group/blob/master/app/util/Page.java
      Кстати, это, вероятно, будущий сайт для нижегородской java user group
      Ответить
      • Каков глубинный смысл магического 1.0?
        Ответить
      • protected String constructQuery(String query) {
                if (orderBy != null) {
                    query = cutOffOrderClause(query);
                    query += "order by " + orderBy + " " + ((order != null) ? order : ASC);
                }
                return "from " + clazz.getSimpleName() + " " + query;
            }
            
            protected String constructCountQuery(String query) {
                String q = cutOffOrderClause(query);
                return "select count(*) from " + clazz.getSimpleName() + " " + q;
            }
            
            private String cutOffOrderClause(String query) {
                int indexOfOrder = query.toLowerCase().indexOf("order by");
                String q = (indexOfOrder >= 0) ? query.substring(0, indexOfOrder) : query;
                return q.trim();
            }

        пардоньте, но за ТАКОЕ надо публично на говнокод - и это при живом import play.db.jpa.JPA; -неужто нельзя было штатными JPA средствами пользоваться?
        Ответить
        • Предложите свой вариант. Вменяемого QueryBuilder'а там нет, иначе бы я вообще не затевал весь этот маскарад.
          Ответить
    • Медленно я дошёл до двери и открыл её, не глядя в глазок. Следом за дверью открылся мой рот; я просто потерял дар речи. На пороге стоял Павел с большим пакетом и радостно улыбался.
      Ответить

    Добавить комментарий