| 
001 /*002  * Copyright 2008-2015 the original author or authors.
 003  *
 004  * Licensed under the Apache License, Version 2.0 (the "License");
 005  * you may not use this file except in compliance with the License.
 006  * You may obtain a copy of the License at
 007  *
 008  *     http://www.apache.org/licenses/LICENSE-2.0
 009  *
 010  * Unless required by applicable law or agreed to in writing, software
 011  * distributed under the License is distributed on an "AS IS" BASIS,
 012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 013  * See the License for the specific language governing permissions and
 014  * limitations under the License.
 015  */
 016 package griffon.core.formatters;
 017
 018 import javax.annotation.Nonnull;
 019 import javax.annotation.Nullable;
 020 import java.util.Arrays;
 021
 022 import static griffon.util.GriffonNameUtils.isBlank;
 023 import static java.util.Objects.requireNonNull;
 024
 025 /**
 026  * @author Andres Almiray
 027  * @since 2.0.0
 028  */
 029 public class BooleanFormatter extends AbstractFormatter<Boolean> {
 030     public static final String PATTERN_BOOL = "boolean";
 031     public static final String PATTERN_QUERY = "query";
 032     public static final String PATTERN_SWITCH = "switch";
 033     public static final String DEFAULT_PATTERN = PATTERN_BOOL;
 034
 035     private static final String[] PATTERNS = new String[]{
 036         PATTERN_BOOL,
 037         PATTERN_QUERY,
 038         PATTERN_SWITCH
 039     };
 040
 041     public static final BooleanFormatter BOOL = new BooleanFormatter(PATTERN_BOOL);
 042     public static final BooleanFormatter QUERY = new BooleanFormatter(PATTERN_QUERY);
 043     public static final BooleanFormatter SWITCH = new BooleanFormatter(PATTERN_SWITCH);
 044
 045     private static final BooleanFormatter[] FORMATTERS = new BooleanFormatter[]{
 046         BOOL,
 047         QUERY,
 048         SWITCH
 049     };
 050
 051     @Nonnull
 052     public static BooleanFormatter getInstance(@Nullable String pattern) {
 053         return new BooleanFormatter(pattern);
 054     }
 055
 056     private final BooleanFormatterDelegate delegate;
 057
 058     public BooleanFormatter() {
 059         this(DEFAULT_PATTERN);
 060     }
 061
 062     protected BooleanFormatter(@Nullable String pattern) {
 063         if (PATTERN_BOOL.equals(pattern)) {
 064             delegate = new BoolBooleanFormatterDelegate();
 065         } else if (PATTERN_QUERY.equals(pattern)) {
 066             delegate = new QueryBooleanFormatterDelegate();
 067         } else if (PATTERN_SWITCH.equals(pattern)) {
 068             delegate = new SwitchBooleanFormatterDelegate();
 069         } else if (isBlank(pattern)) {
 070             delegate = new BoolBooleanFormatterDelegate();
 071         } else {
 072             throw new IllegalArgumentException("Invalid pattern '" + pattern + "'. Valid patterns are " + Arrays.toString(PATTERNS));
 073         }
 074     }
 075
 076     @Nonnull
 077     public String getPattern() {
 078         return delegate.getPattern();
 079     }
 080
 081     @Nullable
 082     public static Boolean parseBoolean(@Nullable String str) throws ParseException {
 083         if (isBlank(str)) return null;
 084         for (BooleanFormatter formatter : FORMATTERS) {
 085             try {
 086                 return formatter.parse(str);
 087             } catch (ParseException e) {
 088                 // ignore
 089             }
 090         }
 091         throw parseError(str, Boolean.class);
 092     }
 093
 094     @Nullable
 095     @Override
 096     public String format(@Nullable Boolean value) {
 097         return value == null ? null : delegate.format(value);
 098     }
 099
 100     @Nullable
 101     @Override
 102     @SuppressWarnings("ConstantConditions")
 103     public Boolean parse(@Nullable String str) throws ParseException {
 104         return isBlank(str) ? null : delegate.parse(str);
 105     }
 106
 107     private static interface BooleanFormatterDelegate {
 108         @Nonnull
 109         String getPattern();
 110
 111         @Nonnull
 112         String format(@Nonnull Boolean value);
 113
 114         @Nonnull
 115         Boolean parse(@Nonnull String str) throws ParseException;
 116     }
 117
 118     private static abstract class AbstractBooleanFormatterDelegate implements BooleanFormatterDelegate {
 119         private final String pattern;
 120         private final String[] tokens;
 121
 122         private AbstractBooleanFormatterDelegate(String pattern, String[] tokens) {
 123             this.pattern = pattern;
 124             this.tokens = tokens;
 125         }
 126
 127         @Nonnull
 128         public String getPattern() {
 129             return pattern;
 130         }
 131
 132         @Nonnull
 133         public String format(@Nonnull Boolean bool) {
 134             requireNonNull(bool, "Can't format given Boolean because it's null");
 135             return bool ? tokens[1] : tokens[0];
 136         }
 137
 138         @Nonnull
 139         public Boolean parse(@Nonnull String str) throws ParseException {
 140             if (tokens[0].equalsIgnoreCase(str)) {
 141                 return Boolean.FALSE;
 142             } else if (tokens[1].equalsIgnoreCase(str)) {
 143                 return Boolean.TRUE;
 144             }
 145             throw parseError(str, Boolean.class);
 146         }
 147     }
 148
 149     private static class BoolBooleanFormatterDelegate extends AbstractBooleanFormatterDelegate {
 150         private BoolBooleanFormatterDelegate() {
 151             super(PATTERN_BOOL, new String[]{"false", "true"});
 152         }
 153     }
 154
 155     private static class QueryBooleanFormatterDelegate extends AbstractBooleanFormatterDelegate {
 156         private QueryBooleanFormatterDelegate() {
 157             super(PATTERN_QUERY, new String[]{"no", "yes"});
 158         }
 159     }
 160
 161     private static class SwitchBooleanFormatterDelegate extends AbstractBooleanFormatterDelegate {
 162         private SwitchBooleanFormatterDelegate() {
 163             super(PATTERN_SWITCH, new String[]{"off", "on"});
 164         }
 165     }
 166 }
 |